diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000000..bf831d7417 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,72 @@ +# Java Maven CircleCI 2.0 configuration file +# +# Check https://circleci.com/docs/2.0/language-java/ for more details +# + +version: 2.1 + +orbs: + slack: circleci/slack@3.4.2 + +executors: + shopizer-ci: + docker: + - image: shopizerecomm/ci:java11 + auth: + username: shopizerecomm + password: $DOCKERHUB_PASSWORD + +working_directory: /tmp + + +# Define the jobs we want to run for this project +jobs: + build: + executor: shopizer-ci + steps: + - checkout + - run: echo "shopizer build and test (1)" + - run: + name: Run shell script + command: | + set -x + /home/shopizer/tools/shopizer.sh tests + - persist_to_workspace: + root: . + paths: + - ./sm-shop + deploy: + machine: true + steps: + - attach_workspace: + at: . + # start proprietary DB using private Docker image + # with credentials stored in the UI + - run: + name: list files in repo + command: ls -al + working_directory: . + - run: + name: list files in shop + command: ls -al + working_directory: ./sm-shop + - run: + name: list files in shop/target + command: ls -al + working_directory: ./sm-shop/target + - run: | + docker login -u shopizerecomm -p $DOCKERHUB_PASSWORD + - run: | + (cd sm-shop && docker build . -t shopizerecomm/shopizer:3.2.1) + - run: + name: push image + command: docker push shopizerecomm/shopizer:3.2.1 + +# Orchestrate our job run sequence +workflows: + build_and_deploy: + jobs: + - build + - deploy: + requires: + - build diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..dc6cb96f87 --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +# Ignored files +*.class +*.jar +*.lst +*/target/ +*.class +*.idea/ +*.iml +*/target/* +.idea/workspace.xml +*.class +/bin/ +/WebContent/ +sm-shop/SALESMANAGER.lock.db +.DS_Store +*/sm-shop/** +.project +sm-admin/**/rebel*.xml +sm-shop/**/rebel*.xml +sm-admin/.project +sm-core-model/.project +sm-core-modules/.project +sm-core/.project +sm-shop/.project +**/bin +**/build +**/.settings +**/.classpath +*/sm-shop/src/main/resources/* +sm-shop/src/main/resources/database.properties +.DS_Store + +.mvnw/*.jar diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100755 index 0000000000..fa4f7b499f --- /dev/null +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,110 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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 + + http://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. +*/ + +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = + "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: : " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100755 index 0000000000..a5fcc11920 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000000..43e874dc3d --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,59 @@ + +pipeline{ + agent { + label 'MVN3' + } + stages{ + stage('clone'){ + steps{ + git url: 'https://github.com/tarunkumarpendem/shopizer.git', + branch: 'master' + } + } + stage ('build') { + steps { + sh 'mvn clean package' + } + } + stage('Build the Code') { + steps { + withSonarQubeEnv('sonarcloud') { + sh script: 'mvn clean package sonar:sonar' + } + } + stage('archiving-artifacts'){ + steps{ + archiveArtifacts artifacts: '**/target/*.jar', followSymlinks: false + } + } + stage('junit_reports'){ + steps{ + junit '**/surefire-reports/*.xml' + } + } + } + +pipeline { + agent {label 'OPENJDK-11-JDK'} + triggers { + pollSCM('0 17 * * *') + } + stages { + stage('vcs') { + steps { + git branch: 'release', url: 'https://github.com/longflewtinku/shopizer.git' + } + } + stage('merge') { + steps { + sh 'git checkout devops' + sh 'git merge release --no-ff' + } + } + stage('build') { + steps { + sh 'mvn clean install' + } + } + } +} \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100755 index 0000000000..490b5c70e9 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,53 @@ +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and +You must cause any modified files to carry prominent notices stating that You changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/README.md b/README.md new file mode 100755 index 0000000000..38445dc01c --- /dev/null +++ b/README.md @@ -0,0 +1,167 @@ +# Shopizer 3 (for java 1.8 +) (tested with Java 11) + + +### Shopizer 2.X (for java 1.8 +) is still available + + +[![last_version](https://img.shields.io/badge/last_version-v3.2.5-blue.svg?style=flat)](https://github.com/shopizer-ecommerce/shopizer/tree/3.2.3) +[![Official site](https://img.shields.io/website-up-down-green-red/https/shields.io.svg?label=official%20site)](http://www.shopizer.com/) +[![Docker Pulls](https://img.shields.io/docker/pulls/shopizerecomm/shopizer.svg)](https://hub.docker.com/r/shopizerecomm/shopizer) +[![stackoverflow](https://img.shields.io/badge/shopizer-stackoverflow-orange.svg?style=flat)](http://stackoverflow.com/questions/tagged/shopizer) +[![CircleCI](https://circleci.com/gh/shopizer-ecommerce/shopizer.svg?style=svg)](https://circleci.com/gh/shopizer-ecommerce/shopizer) + + +Java open source e-commerce software + +Headless commerce and Rest api for ecommerce + +- Catalog +- Shopping cart +- Checkout +- Merchant +- Order +- Customer +- User + +Shopizer Headless commerce consists of the following components: + +- Spring boot Java / Spring boot backend +- Angular administration web application +- React JS front end application + + + +See the demo: +------------------- +Headless demo Available soon + +Demo site for Shopizer 2.X is still available [Legacy Shopizer demo](http://demo.shopizer.com) + +1. Run from Docker images: + +From the command line: + +``` +docker run -p 8080:8080 shopizerecomm/shopizer:latest +``` + +2. Run the administration tool + +â‹…â‹…â‹… Requires the java backend to be running + +``` +docker run \ + -e "APP_BASE_URL=http://localhost:8080/api" \ + -p 82:80 shopizerecomm/shopizer-admin +``` + + +3. Run react shop sample site + +â‹…â‹…â‹… Requires the java backend to be running + +``` +docker run \ + -e "APP_MERCHANT=DEFAULT" + -e "APP_BASE_URL=http://localhost:8080" + -p 80:80 shopizerecomm/shopizer-shop-reactjs +``` + +API documentation: +------------------- + +https://app.swaggerhub.com/apis-docs/shopizer/shopizer-rest-api/3.0.1#/ + +Get the source code: +------------------- +Clone the repository: + + $ git clone git://github.com/shopizer-ecommerce/shopizer.git + + $ git clone git://github.com/shopizer-ecommerce/shopizer-admin.git + + $ git clone git://github.com/shopizer-ecommerce/shopizer-shop-reactjs.git + +If this is your first time using Github, review http://help.github.com to learn the basics. + +You can also download the zip file containing the code from https://github.com/shopizer-ecommerce for each of the the projects above + +To build the application: +------------------- + +1. Shopizer backend + + +From the command line: + + $ cd shopizer + $ mvnw clean install + $ cd sm-shop + $ mvnw spring-boot:run + +2. Shopizer admin + +Form compiling and running Shopizer admin consult the repo README file + +3. Shop sample site + +Form compiling and running Shopizer admin consult the repo README file + + +### Access the application: +------------------- + +Access the headless web application at: http://localhost:8080/swagger-ui.html + + +The instructions above will let you run the application with default settings and configurations. +Please read the instructions on how to connect to MySQL, configure an email server and configure other subsystems + + +### Documentation: +------------------- + +Documentation available + +Api documentation + +ChatOps - Join our Slack channel https://shopizer-slackin.herokuapp.com/ + +More information is available on shopizer web site here + +### Participation: +------------------- + +If you have interest in giving feedback or for participating to Shopizer project in any way +Feel to use the contact form and share your email address +so we can send an invite to our Slack channel + +### How to Contribute: +------------------- +Fork the repository to your GitHub account + +Clone from fork repository +------------------- + + $ git clone https://github.com/yourusername/shopizer.git + +Build application according to steps provided above + +Synchronize lastest version with the upstream +------------------- + + $ git remote add upstream https://github.com/yourusername/shopizer.git + $ git pull upstream 3.2.3 + +Create new branch in your repository +------------------- + + $ git checkout -b branch-name + + +Push your changes to Shopizer +------------------- + +Please open a PR (pull request) in order to have your changes merged to the upstream + + diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md new file mode 100755 index 0000000000..4ddf807747 --- /dev/null +++ b/RELEASE-NOTES.md @@ -0,0 +1,9 @@ +Changes in version 3.2.3 + + +Functionality + +Enabling ProductPriceApi + + + diff --git a/jenkins file b/jenkins file new file mode 100644 index 0000000000..9e702a2cd6 --- /dev/null +++ b/jenkins file @@ -0,0 +1,11 @@ +node("MAVEN3 && NVM && PYTHON3"){ +stage('VCS') { + git branch: 'SPRINT_1_REL', url: 'https://github.com/Sharmila-qt1/shopizer.git' +} +stage("build"){ + sh '/home/ubuntu/workspace/shopizer/mnv package' +} +stage("archieve results"){ + junit '**/surefire-reports/*.xml' + } +} \ No newline at end of file diff --git a/mvnw b/mvnw new file mode 100755 index 0000000000..5551fde8e7 --- /dev/null +++ b/mvnw @@ -0,0 +1,286 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + wget "$jarUrl" -O "$wrapperJarPath" + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + curl -o "$wrapperJarPath" "$jarUrl" + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100755 index 0000000000..48363fa60b --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,161 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" +FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + echo Found %WRAPPER_JAR% +) else ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" + echo Finished downloading %WRAPPER_JAR% +) +@REM End of extension + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000000..0710962899 --- /dev/null +++ b/pom.xml @@ -0,0 +1,598 @@ + + + 4.0.0 + + com.shopizer + shopizer + pom + 3.2.5 + + shopizer + http://ww.shopizer.com + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + + + + + org.springframework.boot + spring-boot-starter-parent + 2.5.12 + + + + sm-core-model + sm-core-modules + sm-core + sm-shop-model + sm-shop + + + + UTF-8 + + + 11 + + ${java.version} + ${java.version} + + 2.11.1 + 2.15.0 + + + 7.5.2 + 27.1-jre + 3.5 + 2.7 + 4.1 + 1.5.1 + 1.3.3 + 1.3.0.Final + + 4.5.2 + 1 + 2.2.4 + 3.0.1 + 1.3.2 + 9.4.18.Final + 9.4.18.Final + 8.0.21 + 18.3.0.0 + 42.2.18 + 1.1.1 + 2.10.2 + 2.10.2 + 2.7.0 + 7.32.0.Final + 0.1.6 + 0.8.0 + + + + 2.9.2 + + + .30 + .37 + + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-cache + + + com.shopizer + sm-core + 3.2.5 + + + com.shopizer + sm-core-model + 3.2.5 + + + com.shopizer + sm-core-modules + 3.2.5 + + + com.shopizer + sm-shop-model + 3.2.5 + + + + + javax.inject + javax.inject + ${javax.inject.version} + + + + + org.apache.commons + commons-lang3 + ${commons-lang.version} + + + + org.mapstruct + mapstruct + ${org.mapstruct.version} + + + + io.jsonwebtoken + jjwt + ${jwt.version} + + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-version-databind} + + + + com.fasterxml.jackson.core + jackson-core + ${jackson-version} + + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson-version} + + + + + javax.mail + mail + 1.4.7 + + + + + com.googlecode.json-simple + json-simple + ${simple-json-version} + + + + mysql + mysql-connector-java + ${mysql-jdbc-version} + + + + + + + + + + + + com.google.maps + google-maps-services + ${google-client-maps-services-version} + + + + org.kie + kie-ci + ${drools.version} + + + com.google.guava + guava + + + + + org.drools + drools-decisiontables + ${drools.version} + + + org.drools + drools-core + ${drools.version} + + + org.drools + drools-compiler + ${drools.version} + + + + org.kie + kie-spring + ${drools.version} + + + + + + org.infinispan + infinispan-core + ${infinispan.version} + + + + org.infinispan + infinispan-cachestore-jdbc + ${infinispan.tree.version} + + + + org.infinispan + infinispan-tree + ${infinispan.version} + + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + + + + commons-validator + commons-validator + ${commons-validator.version} + + + + commons-collections + commons-collections + + + + + + + com.amazonaws + aws-java-sdk-s3 + 1.11.640 + + + + + com.amazonaws + aws-java-sdk-ses + 1.11.640 + + + + + com.google.cloud + google-cloud-storage + 1.74.0 + + + com.google.guava + guava + + + + + + + + + + com.paypal.sdk + merchantsdk + 2.6.109 + + + + + com.stripe + stripe-java + 19.5.0 + + + + + com.braintreepayments.gateway + braintree-java + 2.73.0 + + + + + com.maxmind.geoip2 + geoip2 + ${geoip2.version} + + + + + + + com.google.guava + guava + ${guava.version} + + + + commons-io + commons-io + ${commons-io.version} + + + + commons-fileupload + commons-fileupload + ${commons-fileupload} + + + + io.springfox + springfox-swagger2 + ${swagger.version} + + + + io.springfox + springfox-swagger-ui + ${swagger.version} + + + + javax.annotation + javax.annotation-api + ${javax.annotation} + + + + + + + + + + + javax.inject + javax.inject + + + + javax.validation + validation-api + + + + + org.apache.commons + commons-lang3 + + + + + + + com.fasterxml.jackson.core + jackson-databind + + + + com.fasterxml.jackson.core + jackson-core + + + + com.fasterxml.jackson.core + jackson-annotations + + + + + net.sf.ehcache + ehcache + + + + + javax.mail + javax.mail-api + + + + + javax.mail + mail + + + + + com.googlecode.json-simple + json-simple + + + junit + junit + + + + + + + + mysql + mysql-connector-java + + + + + + + + + + org.junit.vintage + junit-vintage-engine + test + + + + + + + + + oss-sonatype + oss-sonatype + https://s01.oss.sonatype.org/content/repositories/snapshots/ + + true + + + + spring-releases + Spring Releases + https://repo.spring.io/libs-release + + + + spring-milestone + Spring Milestone + https://repo.spring.io/milestone/ + + + org.jboss.repository.releases + JBoss Maven Release Repository + https://repository.jboss.org/nexus/content/repositories/releases + + + + + + spring-releases + Spring Releases + https://repo.spring.io/libs-release + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${maven.compiler.source} + ${maven.compiler.target} + + + org.mapstruct + mapstruct-processor + ${org.mapstruct.version} + + + + + + + + com.github.spotbugs + spotbugs-maven-plugin + 3.1.8 + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true + + ossrh + https://oss.sonatype.org/ + true + + + + + org.apache.maven.plugins + maven-release-plugin + 2.5.3 + + true + false + release + deploy + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar-no-fork + + + + + + + + + + + + \ No newline at end of file diff --git a/sm-core-model/.gitignore b/sm-core-model/.gitignore new file mode 100755 index 0000000000..b83d22266a --- /dev/null +++ b/sm-core-model/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/sm-core-model/.mvn/wrapper/MavenWrapperDownloader.java b/sm-core-model/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100755 index 0000000000..fa4f7b499f --- /dev/null +++ b/sm-core-model/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,110 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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 + + http://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. +*/ + +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = + "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: : " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/sm-core-model/.mvn/wrapper/maven-wrapper.properties b/sm-core-model/.mvn/wrapper/maven-wrapper.properties new file mode 100755 index 0000000000..a5fcc11920 --- /dev/null +++ b/sm-core-model/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip \ No newline at end of file diff --git a/sm-core-model/mvnw b/sm-core-model/mvnw new file mode 100755 index 0000000000..5551fde8e7 --- /dev/null +++ b/sm-core-model/mvnw @@ -0,0 +1,286 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + wget "$jarUrl" -O "$wrapperJarPath" + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + curl -o "$wrapperJarPath" "$jarUrl" + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/sm-core-model/mvnw.cmd b/sm-core-model/mvnw.cmd new file mode 100755 index 0000000000..48363fa60b --- /dev/null +++ b/sm-core-model/mvnw.cmd @@ -0,0 +1,161 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" +FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + echo Found %WRAPPER_JAR% +) else ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" + echo Finished downloading %WRAPPER_JAR% +) +@REM End of extension + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/sm-core-model/pom.xml b/sm-core-model/pom.xml new file mode 100755 index 0000000000..40ccb0c8c6 --- /dev/null +++ b/sm-core-model/pom.xml @@ -0,0 +1,192 @@ + + + 4.0.0 + + + com.shopizer + shopizer + 3.2.5 + + + + sm-core-model + sm-core-modules is used for create new external modules implementation deployed in maven. + sm-core-model + http://www.shopizer.com + + + 11 + ${java.version} + ${java.version} + + + + + scm:git:git://github.com:shopizer-ecommerce/shopizer-sm-core-model.git + scm:git:ssh://github.com:shopizer-ecommerce/shopizer-sm-core-model.git + https://github.com/shopizer-ecommerce/shopizer-sm-core-model + + + + + + + ossrh + https://s01.oss.sonatype.org/content/repositories/snapshots/ + + + ossrh + https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + + + + + + Shopizer Team + contact@shopizer.com + Shopizer + http://www.shopizer.com + + + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + javax.validation + validation-api + + + + com.fasterxml.jackson.core + jackson-annotations + + + + com.fasterxml.jackson.core + jackson-databind + + + + + org.json + json + 20211205 + + + + + com.googlecode.json-simple + json-simple + + + + + + org.apache.commons + commons-lang3 + + + + + + org.springframework + spring-webmvc + + + + + + commons-io + commons-io + + + + + commons-fileupload + commons-fileupload + + + + + + + + + + + + + + release + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true + + ossrh + https://s01.oss.sonatype.org + true + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + + + + diff --git a/sm-core-model/src/main/java/com/salesmanager/core/business/exception/ConversionException.java b/sm-core-model/src/main/java/com/salesmanager/core/business/exception/ConversionException.java new file mode 100755 index 0000000000..4a245f5134 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/business/exception/ConversionException.java @@ -0,0 +1,31 @@ +/** + * + */ +package com.salesmanager.core.business.exception; + +/** + * @author Umesh A + * + */ +public class ConversionException extends Exception +{ + private static final long serialVersionUID = 687400310032876603L; + + public ConversionException(final String msg, final Throwable cause) + { + super(msg, cause); + } + + public ConversionException(final String msg) + { + super(msg); + } + + public ConversionException(Throwable t) + { + super(t); + } + + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/business/exception/ServiceException.java b/sm-core-model/src/main/java/com/salesmanager/core/business/exception/ServiceException.java new file mode 100755 index 0000000000..2452c45c5e --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/business/exception/ServiceException.java @@ -0,0 +1,72 @@ +package com.salesmanager.core.business.exception; + +/** + *

Exception générée par les services de l'application.

+ */ +public class ServiceException extends Exception { + + private static final long serialVersionUID = -6854945379036729034L; + private int exceptionType = 0;//regular error + + + public final static int EXCEPTION_ERROR = 500; + + public final static int EXCEPTION_VALIDATION = 99; + public final static int EXCEPTION_PAYMENT_DECLINED = 100; + public final static int EXCEPTION_TRANSACTION_DECLINED = 101; + public final static int EXCEPTION_INVENTORY_MISMATCH = 120; + + private String messageCode = null; + + + + public void setMessageCode(String messageCode) { + this.messageCode = messageCode; + } + + public ServiceException() { + super(); + } + + public ServiceException(String messageCode) { + super(); + this.messageCode = messageCode; + } + + public ServiceException(String message, Throwable cause) { + super(message, cause); + } + + public ServiceException(Throwable cause) { + super(cause.getMessage(), cause); + } + + public ServiceException(int exceptionType) { + super(); + this.exceptionType = exceptionType; + } + + public ServiceException(int exceptionType, String message) { + super(message); + this.exceptionType = exceptionType; + } + + public ServiceException(int exceptionType, String message, String messageCode) { + super(message); + this.messageCode = messageCode; + this.exceptionType = exceptionType; + } + + public int getExceptionType() { + return exceptionType; + } + + public void setExceptionType(int exceptionType) { + this.exceptionType = exceptionType; + } + + public String getMessageCode() { + return messageCode; + } + +} \ No newline at end of file diff --git a/sm-core-model/src/main/java/com/salesmanager/core/constants/MeasureUnit.java b/sm-core-model/src/main/java/com/salesmanager/core/constants/MeasureUnit.java new file mode 100755 index 0000000000..51332ed4b9 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/constants/MeasureUnit.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.constants; + +public enum MeasureUnit { + + KG, LB, CM, IN + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/constants/SchemaConstant.java b/sm-core-model/src/main/java/com/salesmanager/core/constants/SchemaConstant.java new file mode 100755 index 0000000000..615fdbb36d --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/constants/SchemaConstant.java @@ -0,0 +1,279 @@ +package com.salesmanager.core.constants; + +import java.util.HashMap; +import java.util.Locale; + +public class SchemaConstant { + + public final static String SALESMANAGER_SCHEMA = "SALESMANAGER"; + + /** + * Languages iso codes + * + */ + //public static final String[] LANGUAGE_ISO_CODE = {"en", "fr", "ru", "es", "ar"}; + + @Deprecated + public static final String[] LANGUAGE_ISO_CODE = {"en", "fr", "es"}; //which descriptions will ve used for reference data + + public final static int DESCRIPTION_ID_ALLOCATION_SIZE = 1; + public final static int DESCRIPTION_ID_START_VALUE = 2000; + + /** + * All regions + */ + public static final String ALL_REGIONS = "*"; + + /** + * Country iso codes + */ + public static final String[] COUNTRY_ISO_CODE = { "AF","AX","AL","DZ", + "AS","AD","AO","AI","AQ","AG","AR","AM","AW","AU","AT","AZ","BS","BH", + "BD","BB","BY","BE","BZ","BJ","BM","BT","BO","BA","BW","BV","BR","IO", + "BN","BG","BF","BI","KH","CM","CA","CV","KY","CF","TD","CL","CN","CX", + "CC","CO","KM","CG","CD","CK","CR","CI","HR","CU","CY","CZ","DK","DJ", + "DM","DO","EC","EG","SV","GQ","ER","EE","ET","FK","FO","FJ","FI","FR", + "GF","PF","TF","GA","GM","GE","DE","GH","GI","GR","GL","GD","GP","GU", + "GT","GG","GN","GW","GY","HT","HM","VA","HN","HK","HU","IS","IN","ID", + "IR","IQ","IE","IM","IL","IT","JM","JP","JE","JO","KZ","KE","KI","KP", + "KR","KW","KG","LA","LV","LB","LS","LR","LY","LI","LT","LU","MO","MK", + "MG","MW","MY","MV","ML","MT","MH","MQ","MR","MU","YT","MX","FM","MD", + "MC","MN","ME","MS","MA","MZ","MM","NA","NR","NP","NL","AN","NC","NZ", + "NI","NE","NG","NU","NF","MP","NO","OM","PK","PW","PS","PA","PG","PY", + "PE","PH","PN","PL","PT","PR","QA","RE","RO","RU","RW","SH","KN","LC", + "PM","VC","WS","SM","ST","SA","SN","RS","SC","SL","SG","SK","SI","SB", + "SO","ZA","GS","ES","LK","SD","SR","SJ","SZ","SE","CH","SY","TW","TJ", + "TZ","TH","TL","TG","TK","TO","TT","TN","TR","TM","TC","TV","UG","UA", + "AE","GB","US","UM","UY","UZ","VU","VE","VN","VG","VI","WF","EH", + "YE","ZM","ZW" }; + + /** + * Locale per country iso codes + */ + public static final HashMap LOCALES = new HashMap(); + + static { + for (Locale locale : Locale.getAvailableLocales()) { + LOCALES.put(locale.getCountry(), locale); + } + } + + /** + * Currency codes with name + */ + public static final HashMap CURRENCY_MAP = new HashMap(); + + static { + CURRENCY_MAP.put("AFN", "Afghani"); + CURRENCY_MAP.put("EUR", "Euro"); + CURRENCY_MAP.put("ALL", "Lek"); + CURRENCY_MAP.put("DZD", "Algerian Dinar"); + CURRENCY_MAP.put("USD", "US Dollar"); + CURRENCY_MAP.put("AOA", "Kwanza"); + CURRENCY_MAP.put("XCD", "East Caribbean Dollar"); + CURRENCY_MAP.put("ARS", "Argentine Peso"); + CURRENCY_MAP.put("AMD", "Armenian Dram"); + CURRENCY_MAP.put("AWG", "Aruban Florin"); + CURRENCY_MAP.put("AUD", "Australian Dollar"); + CURRENCY_MAP.put("AZN", "Azerbaijanian Manat"); + CURRENCY_MAP.put("BSD", "Bahamian Dollar"); + CURRENCY_MAP.put("BHD", "Bahraini Dinar"); + CURRENCY_MAP.put("BDT", "Taka"); + CURRENCY_MAP.put("BBD", "Barbados Dollar"); + CURRENCY_MAP.put("BYR", "Belarussian Ruble"); + CURRENCY_MAP.put("BZD", "Belize Dollar"); + CURRENCY_MAP.put("XOF", "CFA Franc BCEAO"); + CURRENCY_MAP.put("BMD", "Bermudian Dollar"); + CURRENCY_MAP.put("BTN", "Ngultrum"); + CURRENCY_MAP.put("INR", "Indian Rupee"); + CURRENCY_MAP.put("BOB", "Boliviano"); + CURRENCY_MAP.put("BOV", "Mvdol"); + CURRENCY_MAP.put("BAM", "Convertible Mark"); + CURRENCY_MAP.put("BWP", "Pula"); + CURRENCY_MAP.put("NOK", "Norwegian Krone"); + CURRENCY_MAP.put("BRL", "Brazilian Real"); + CURRENCY_MAP.put("BND", "Brunei Dollar"); + CURRENCY_MAP.put("BGN", "Bulgarian Lev"); + CURRENCY_MAP.put("XOF", "CFA Franc BCEAO"); + CURRENCY_MAP.put("BIF", "Burundi Franc"); + CURRENCY_MAP.put("KHR", "Riel"); + CURRENCY_MAP.put("XAF", "CFA Franc BEAC"); + CURRENCY_MAP.put("CAD", "Canadian Dollar"); + CURRENCY_MAP.put("CVE", "Cape Verde Escudo"); + CURRENCY_MAP.put("KYD", "Cayman Islands Dollar"); + CURRENCY_MAP.put("CLF", "Unidades de fomento"); + CURRENCY_MAP.put("CLP", "Chilean Peso"); + CURRENCY_MAP.put("CNY", "Yuan Renminbi"); + CURRENCY_MAP.put("COP", "Colombian Peso"); + //CURRENCY_MAP.put("COU", "Unidad de Valor Real"); + CURRENCY_MAP.put("KMF", "Comoro Franc"); + CURRENCY_MAP.put("XAF", "CFA Franc BEAC"); + CURRENCY_MAP.put("CDF", "Congolese Franc"); + CURRENCY_MAP.put("NZD", "New Zealand Dollar"); + CURRENCY_MAP.put("CRC", "Costa Rican Colon"); + CURRENCY_MAP.put("XOF", "CFA Franc BCEAO"); + CURRENCY_MAP.put("HRK", "Croatian Kuna"); + //CURRENCY_MAP.put("CUC", "Peso Convertible"); + CURRENCY_MAP.put("CUP", "Cuban Peso"); + CURRENCY_MAP.put("ANG", "Netherlands Antillean Guilder"); + CURRENCY_MAP.put("CZK", "Czech Koruna"); + CURRENCY_MAP.put("DKK", "Danish Krone"); + CURRENCY_MAP.put("DJF", "Djibouti Franc"); + CURRENCY_MAP.put("XCD", "East Caribbean Dollar"); + CURRENCY_MAP.put("DOP", "Dominican Peso"); + CURRENCY_MAP.put("EGP", "Egyptian Pound"); + CURRENCY_MAP.put("SVC", "El Salvador Colon"); + CURRENCY_MAP.put("XAF", "CFA Franc BEAC"); + CURRENCY_MAP.put("ERN", "Nakfa"); + CURRENCY_MAP.put("ETB", "Ethiopian Birr"); + CURRENCY_MAP.put("FKP", "Falkland Islands Pound"); + CURRENCY_MAP.put("DKK", "Danish Krone"); + CURRENCY_MAP.put("FJD", "Fiji Dollar"); + CURRENCY_MAP.put("XPF", "CFP Franc"); + CURRENCY_MAP.put("XAF", "CFA Franc BEAC"); + CURRENCY_MAP.put("GMD", "Dalasi"); + CURRENCY_MAP.put("GEL", "Lari"); + CURRENCY_MAP.put("GHS", "Ghana Cedi"); + CURRENCY_MAP.put("GIP", "Gibraltar Pound"); + CURRENCY_MAP.put("DKK", "Danish Krone"); + CURRENCY_MAP.put("XCD", "East Caribbean Dollar"); + CURRENCY_MAP.put("GTQ", "Quetzal"); + CURRENCY_MAP.put("GBP", "Pound Sterling"); + CURRENCY_MAP.put("GNF", "Guinea Franc"); + CURRENCY_MAP.put("XOF", "CFA Franc BCEAO"); + CURRENCY_MAP.put("GYD", "Guyana Dollar"); + CURRENCY_MAP.put("HTG", "Gourde"); + CURRENCY_MAP.put("HNL", "Lempira"); + CURRENCY_MAP.put("HKD", "Hong Kong Dollar"); + CURRENCY_MAP.put("HUF", "Forint"); + CURRENCY_MAP.put("ISK", "Iceland Krona"); + CURRENCY_MAP.put("INR", "Indian Rupee"); + CURRENCY_MAP.put("IDR", "Rupiah"); + CURRENCY_MAP.put("XDR", "SDR (Special Drawing Right)"); + CURRENCY_MAP.put("IRR", "Iranian Rial"); + CURRENCY_MAP.put("IQD", "Iraqi Dinar"); + CURRENCY_MAP.put("GBP", "Pound Sterling"); + CURRENCY_MAP.put("ILS", "New Israeli Sheqel"); + CURRENCY_MAP.put("JMD", "Jamaican Dollar"); + CURRENCY_MAP.put("JPY", "Yen"); + CURRENCY_MAP.put("GBP", "Pound Sterling"); + CURRENCY_MAP.put("JOD", "Jordanian Dinar"); + CURRENCY_MAP.put("KZT", "Tenge"); + CURRENCY_MAP.put("KES", "Kenyan Shilling"); + CURRENCY_MAP.put("AUD", "Australian Dollar"); + CURRENCY_MAP.put("KPW", "North Korean Won"); + CURRENCY_MAP.put("KRW", "Won"); + CURRENCY_MAP.put("KWD", "Kuwaiti Dinar"); + CURRENCY_MAP.put("KGS", "Som"); + CURRENCY_MAP.put("LAK", "Kip"); + CURRENCY_MAP.put("LVL", "Latvian Lats"); + CURRENCY_MAP.put("LBP", "Lebanese Pound"); + CURRENCY_MAP.put("LSL", "Loti"); + CURRENCY_MAP.put("ZAR", "Rand"); + CURRENCY_MAP.put("LRD", "Liberian Dollar"); + CURRENCY_MAP.put("LYD", "Libyan Dinar"); + CURRENCY_MAP.put("CHF", "Swiss Franc"); + CURRENCY_MAP.put("LTL", "Lithuanian Litas"); + CURRENCY_MAP.put("EUR", "Euro"); + CURRENCY_MAP.put("MOP", "Pataca"); + CURRENCY_MAP.put("MKD", "Denar"); + CURRENCY_MAP.put("MGA", "Malagasy Ariary"); + CURRENCY_MAP.put("MWK", "Kwacha"); + CURRENCY_MAP.put("MYR", "Malaysian Ringgit"); + CURRENCY_MAP.put("MVR", "Rufiyaa"); + CURRENCY_MAP.put("XOF", "CFA Franc BCEAO"); + CURRENCY_MAP.put("MRO", "Ouguiya"); + CURRENCY_MAP.put("MUR", "Mauritius Rupee"); + //CURRENCY_MAP.put("XUA", "ADB Unit of Account"); + CURRENCY_MAP.put("MXN", "Mexican Peso"); + CURRENCY_MAP.put("MXV", "Mexican Unidad de Inversion (UDI)"); + CURRENCY_MAP.put("MDL", "Moldovan Leu"); + CURRENCY_MAP.put("MNT", "Tugrik"); + CURRENCY_MAP.put("XCD", "East Caribbean Dollar"); + CURRENCY_MAP.put("MAD", "Moroccan Dirham"); + CURRENCY_MAP.put("MZN", "Mozambique Metical"); + CURRENCY_MAP.put("MMK", "Kyat"); + CURRENCY_MAP.put("NAD", "Namibia Dollar"); + CURRENCY_MAP.put("ZAR", "Rand"); + CURRENCY_MAP.put("NPR", "Nepalese Rupee"); + CURRENCY_MAP.put("XPF", "CFP Franc"); + CURRENCY_MAP.put("NZD", "New Zealand Dollar"); + CURRENCY_MAP.put("NIO", "Cordoba Oro"); + CURRENCY_MAP.put("XOF", "CFA Franc BCEAO"); + CURRENCY_MAP.put("NGN", "Naira"); + CURRENCY_MAP.put("NZD", "New Zealand Dollar"); + CURRENCY_MAP.put("AUD", "Australian Dollar"); + CURRENCY_MAP.put("NOK", "Norwegian Krone"); + CURRENCY_MAP.put("OMR", "Rial Omani"); + CURRENCY_MAP.put("PKR", "Pakistan Rupee"); + CURRENCY_MAP.put("PAB", "Balboa"); + CURRENCY_MAP.put("PGK", "Kina"); + CURRENCY_MAP.put("PYG", "Guarani"); + CURRENCY_MAP.put("PEN", "Nuevo Sol"); + CURRENCY_MAP.put("PHP", "Philippine Peso"); + CURRENCY_MAP.put("NZD", "New Zealand Dollar"); + CURRENCY_MAP.put("PLN", "Zloty"); + CURRENCY_MAP.put("USD", "US Dollar"); + CURRENCY_MAP.put("QAR", "Qatari Rial"); + CURRENCY_MAP.put("RON", "New Romanian Leu"); + CURRENCY_MAP.put("RUB", "Russian Ruble"); + CURRENCY_MAP.put("RWF", "Rwanda Franc"); + CURRENCY_MAP.put("SHP", "Saint Helena Pound"); + CURRENCY_MAP.put("XCD", "East Caribbean Dollar"); + CURRENCY_MAP.put("WST", "Tala"); + CURRENCY_MAP.put("STD", "Dobra"); + CURRENCY_MAP.put("SAR", "Saudi Riyal"); + CURRENCY_MAP.put("XOF", "CFA Franc BCEAO"); + CURRENCY_MAP.put("RSD", "Serbian Dinar"); + CURRENCY_MAP.put("SCR", "Seychelles Rupee"); + CURRENCY_MAP.put("SLL", "Leone"); + CURRENCY_MAP.put("SGD", "Singapore Dollar"); + CURRENCY_MAP.put("ANG", "Netherlands Antillean Guilder"); + //CURRENCY_MAP.put("XSU", "Sucre"); + CURRENCY_MAP.put("SBD", "Solomon Islands Dollar"); + CURRENCY_MAP.put("SOS", "Somali Shilling"); + CURRENCY_MAP.put("ZAR", "Rand"); + //CURRENCY_MAP.put("SSP", "South Sudanese Pound"); + CURRENCY_MAP.put("LKR", "Sri Lanka Rupee"); + CURRENCY_MAP.put("SDG", "Sudanese Pound"); + CURRENCY_MAP.put("SRD", "Surinam Dollar"); + CURRENCY_MAP.put("NOK", "Norwegian Krone"); + CURRENCY_MAP.put("SZL", "Lilangeni"); + CURRENCY_MAP.put("SEK", "Swedish Krona"); + //CURRENCY_MAP.put("CHE", "WIR Euro"); + CURRENCY_MAP.put("CHF", "Swiss Franc"); + //CURRENCY_MAP.put("CHW", "WIR Franc"); + CURRENCY_MAP.put("SYP", "Syrian Pound"); + CURRENCY_MAP.put("TWD", "New Taiwan Dollar"); + CURRENCY_MAP.put("TJS", "Somoni"); + CURRENCY_MAP.put("TZS", "Tanzanian Shilling"); + CURRENCY_MAP.put("THB", "Baht"); + CURRENCY_MAP.put("USD", "US Dollar"); + CURRENCY_MAP.put("XOF", "CFA Franc BCEAO"); + CURRENCY_MAP.put("NZD", "New Zealand Dollar"); + CURRENCY_MAP.put("TTD", "Trinidad and Tobago Dollar"); + CURRENCY_MAP.put("TND", "Tunisian Dinar"); + CURRENCY_MAP.put("TRY", "Turkish Lira"); + //CURRENCY_MAP.put("TMT", "Turkmenistan New Manat"); + CURRENCY_MAP.put("AUD", "Australian Dollar"); + CURRENCY_MAP.put("UGX", "Uganda Shilling"); + CURRENCY_MAP.put("UAH", "Hryvnia"); + CURRENCY_MAP.put("AED", "UAE Dirham"); + CURRENCY_MAP.put("GBP", "Pound Sterling"); + //CURRENCY_MAP.put("UYI", "Uruguay Peso en Unidades Indexadas (URUIURUI)"); + CURRENCY_MAP.put("UYU", "Peso Uruguayo"); + CURRENCY_MAP.put("UZS", "Uzbekistan Sum"); + CURRENCY_MAP.put("VUV", "Vatu"); + CURRENCY_MAP.put("VEF", "Bolivar Fuerte"); + CURRENCY_MAP.put("VND", "Dong"); + CURRENCY_MAP.put("USD", "US Dollar"); + CURRENCY_MAP.put("XPF", "CFP Franc"); + CURRENCY_MAP.put("MAD", "Moroccan Dirham"); + CURRENCY_MAP.put("YER", "Yemeni Rial"); + CURRENCY_MAP.put("ZMK", "Zambian Kwacha"); + //CURRENCY_MAP.put("ZWL", "Zimbabwe Dollar"); + + + + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/catalog/Catalog.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/catalog/Catalog.java new file mode 100644 index 0000000000..717addd4f1 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/catalog/Catalog.java @@ -0,0 +1,171 @@ +package com.salesmanager.core.model.catalog.catalog; + + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + +/** + * Allows grouping products and category + * Catalog + * - category 1 + * - category 2 + * + * - product 1 + * - product 2 + * - product 3 + * - product 4 + * + * @author carlsamson + * + */ + + +@Entity +@EntityListeners(value = com.salesmanager.core.model.common.audit.AuditListener.class) +@Table(name = "CATALOG", +uniqueConstraints=@UniqueConstraint(columnNames = {"MERCHANT_ID", "CODE"})) +public class Catalog extends SalesManagerEntity implements Auditable { + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.TABLE, + generator = "TABLE_GEN") + @TableGenerator(name = "TABLE_GEN", + table = "SM_SEQUENCER", + pkColumnName = "SEQ_NAME", + valueColumnName = "SEQ_COUNT", + pkColumnValue = "CATALOG_SEQ_NEXT_VAL", + allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, + initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE + ) + private Long id; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @Valid + @OneToMany(mappedBy="catalog", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private Set entry = new HashSet(); + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore merchantStore; + + + @Column(name = "VISIBLE") + private boolean visible; + + @Column(name="DEFAULT_CATALOG") + private boolean defaultCatalog; + + @NotEmpty + @Column(name="CODE", length=100, nullable=false) + private String code; + + @Column(name = "SORT_ORDER") + private Integer sortOrder = 0; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public Catalog() { + } + + public Catalog(MerchantStore store) { + this.merchantStore = store; + this.id = 0L; + } + + @Override + public Long getId() { + return this.id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection auditSection) { + this.auditSection = auditSection; + } + + + public Integer getSortOrder() { + return sortOrder; + } + + public void setSortOrder(Integer sortOrder) { + this.sortOrder = sortOrder; + } + + public boolean isVisible() { + return visible; + } + + public void setVisible(boolean visible) { + this.visible = visible; + } + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public Set getEntry() { + return entry; + } + + public void setEntry(Set entry) { + this.entry = entry; + } + + public boolean isDefaultCatalog() { + return defaultCatalog; + } + + public void setDefaultCatalog(boolean defaultCatalog) { + this.defaultCatalog = defaultCatalog; + } + + + +} \ No newline at end of file diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/catalog/CatalogCategoryEntry.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/catalog/CatalogCategoryEntry.java new file mode 100644 index 0000000000..b38636f816 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/catalog/CatalogCategoryEntry.java @@ -0,0 +1,108 @@ +package com.salesmanager.core.model.catalog.catalog; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; + +@Entity +@EntityListeners(value = com.salesmanager.core.model.common.audit.AuditListener.class) +@Table(name = "CATALOG_ENTRY",uniqueConstraints= +@UniqueConstraint(columnNames = {"CATEGORY_ID", "CATALOG_ID"}) ) +public class CatalogCategoryEntry extends SalesManagerEntity implements Auditable { + + + @Embedded + private AuditSection auditSection = new AuditSection(); + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.TABLE, + generator = "TABLE_GEN") + + @TableGenerator(name = "TABLE_GEN", + table = "SM_SEQUENCER", + pkColumnName = "SEQ_NAME", + valueColumnName = "SEQ_COUNT", + allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, + initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE, + pkColumnValue = "CATALOG_ENT_SEQ_NEXT_VAL") + private Long id; + + @ManyToOne + @JoinColumn(name = "CATEGORY_ID", nullable = false) + Category category; + + @ManyToOne + @JoinColumn(name = "CATALOG_ID", nullable = false) + private Catalog catalog; + + //TODO d products ???? + + @Column(name = "VISIBLE") + private boolean visible; + + public Category getCategory() { + return category; + } + + public void setCategory(Category category) { + this.category = category; + } + + public Catalog getCatalog() { + return catalog; + } + + public void setCatalog(Catalog catalog) { + this.catalog = catalog; + } + + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + + } + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection audit) { + auditSection = audit; + + } + + public boolean isVisible() { + return visible; + } + + public void setVisible(boolean visible) { + this.visible = visible; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/category/Category.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/category/Category.java new file mode 100755 index 0000000000..af30c368be --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/category/Category.java @@ -0,0 +1,228 @@ +package com.salesmanager.core.model.catalog.category; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; + +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + +@Entity +@EntityListeners(value = com.salesmanager.core.model.common.audit.AuditListener.class) +@Table(name = "CATEGORY", + indexes = @Index(columnList = "LINEAGE"), + uniqueConstraints= + @UniqueConstraint(columnNames = {"MERCHANT_ID", "CODE"}) ) + + +public class Category extends SalesManagerEntity implements Auditable { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "CATEGORY_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "CATEGORY_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @Valid + @OneToMany(mappedBy="category", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private Set descriptions = new HashSet(); + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore merchantStore; + + @ManyToOne + @JoinColumn(name = "PARENT_ID") + private Category parent; + + @OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE) + private List categories = new ArrayList(); + + @Column(name = "CATEGORY_IMAGE", length=100) + private String categoryImage; + + @Column(name = "SORT_ORDER") + private Integer sortOrder = 0; + + @Column(name = "CATEGORY_STATUS") + private boolean categoryStatus; + + @Column(name = "VISIBLE") + private boolean visible; + + @Column(name = "DEPTH") + private Integer depth; + + @Column(name = "LINEAGE") + private String lineage; + + @Column(name="FEATURED") + private boolean featured; + + @NotEmpty + @Column(name="CODE", length=100, nullable=false) + private String code; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public Category() { + } + + public Category(MerchantStore store) { + this.merchantStore = store; + this.id = 0L; + } + + @Override + public Long getId() { + return this.id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection auditSection) { + this.auditSection = auditSection; + } + + + public String getCategoryImage() { + return categoryImage; + } + + public void setCategoryImage(String categoryImage) { + this.categoryImage = categoryImage; + } + + public Integer getSortOrder() { + return sortOrder; + } + + public void setSortOrder(Integer sortOrder) { + this.sortOrder = sortOrder; + } + + public boolean isCategoryStatus() { + return categoryStatus; + } + + public void setCategoryStatus(boolean categoryStatus) { + this.categoryStatus = categoryStatus; + } + + public boolean isVisible() { + return visible; + } + + public void setVisible(boolean visible) { + this.visible = visible; + } + + public Integer getDepth() { + return depth; + } + + public void setDepth(Integer depth) { + this.depth = depth; + } + + public String getLineage() { + return lineage; + } + + public void setLineage(String lineage) { + this.lineage = lineage; + } + + public Category getParent() { + return parent; + } + + public void setParent(Category parent) { + this.parent = parent; + } + + + + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public List getCategories() { + return categories; + } + + public void setCategories(List categories) { + this.categories = categories; + } + + public CategoryDescription getDescription() { + if(descriptions!=null && descriptions.size()>0) { + return descriptions.iterator().next(); + } + + return null; + } + + public boolean isFeatured() { + return featured; + } + + public void setFeatured(boolean featured) { + this.featured = featured; + } + + public Set getDescriptions() { + return descriptions; + } + + public void setDescriptions(Set descriptions) { + this.descriptions = descriptions; + } + +} \ No newline at end of file diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/category/CategoryDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/category/CategoryDescription.java new file mode 100755 index 0000000000..9ecfe8e5fd --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/category/CategoryDescription.java @@ -0,0 +1,106 @@ +package com.salesmanager.core.model.catalog.category; + + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.description.Description; +import com.salesmanager.core.model.reference.language.Language; + + +@Entity +@Table(name="CATEGORY_DESCRIPTION",uniqueConstraints={ + @UniqueConstraint(columnNames={ + "CATEGORY_ID", + "LANGUAGE_ID" + }) + } +) +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "category_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +public class CategoryDescription extends Description { + private static final long serialVersionUID = 1L; + + @JsonIgnore + @ManyToOne(targetEntity = Category.class) + @JoinColumn(name = "CATEGORY_ID", nullable = false) + private Category category; + + @Column(name="SEF_URL", length=120) + private String seUrl; + + @Column(name = "CATEGORY_HIGHLIGHT") + private String categoryHighlight; + + public String getCategoryHighlight() { + return categoryHighlight; + } + + public void setCategoryHighlight(String categoryHighlight) { + this.categoryHighlight = categoryHighlight; + } + + @Column(name="META_TITLE", length=120) + private String metatagTitle; + + @Column(name="META_KEYWORDS") + private String metatagKeywords; + + @Column(name="META_DESCRIPTION") + private String metatagDescription; + + public CategoryDescription() { + } + + public CategoryDescription(String name, Language language) { + this.setName(name); + this.setLanguage(language); + super.setId(0L); + } + + public String getSeUrl() { + return seUrl; + } + + public void setSeUrl(String seUrl) { + this.seUrl = seUrl; + } + + public String getMetatagTitle() { + return metatagTitle; + } + + public void setMetatagTitle(String metatagTitle) { + this.metatagTitle = metatagTitle; + } + + public String getMetatagKeywords() { + return metatagKeywords; + } + + public void setMetatagKeywords(String metatagKeywords) { + this.metatagKeywords = metatagKeywords; + } + + public String getMetatagDescription() { + return metatagDescription; + } + + public void setMetatagDescription(String metatagDescription) { + this.metatagDescription = metatagDescription; + } + + public Category getCategory() { + return category; + } + + public void setCategory(Category category) { + this.category = category; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/marketplace/Catalog.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/marketplace/Catalog.java new file mode 100755 index 0000000000..0b1b6c1911 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/marketplace/Catalog.java @@ -0,0 +1,82 @@ +package com.salesmanager.core.model.catalog.marketplace; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.Embedded; + +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + +/** + * A catalog is used to classify products of a given merchant + * to be displayed in a specific marketplace + * @author c.samson + * + */ +public class Catalog extends SalesManagerEntity implements Auditable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private Long id; + + private MerchantStore store; + + private String code; + + private List descriptions = new ArrayList(); + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection audit) { + this.auditSection = auditSection; + } + + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public MerchantStore getStore() { + return store; + } + + public void setStore(MerchantStore store) { + this.store = store; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/marketplace/CatalogDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/marketplace/CatalogDescription.java new file mode 100755 index 0000000000..ac8aaa3d1f --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/marketplace/CatalogDescription.java @@ -0,0 +1,48 @@ +package com.salesmanager.core.model.catalog.marketplace; + + +import com.salesmanager.core.model.common.description.Description; +import com.salesmanager.core.model.reference.language.Language; + + +/*@Entity +@Table(name="CATEGORY_DESCRIPTION",uniqueConstraints={ + @UniqueConstraint(columnNames={ + "CATEGORY_ID", + "LANGUAGE_ID" + }) + } +)*/ +public class CatalogDescription extends Description { + + + +/** + * + */ + private static final long serialVersionUID = 1L; + /* @ManyToOne(targetEntity = Catalog.class) + @JoinColumn(name = "CATALOG_ID", nullable = false)*/ + private Catalog catalog; + + + + public CatalogDescription() { + } + + public CatalogDescription(String name, Language language) { + this.setName(name); + this.setLanguage(language); + super.setId(0L); + } + + public Catalog getCatalog() { + return catalog; + } + + public void setCatalog(Catalog catalog) { + this.catalog = catalog; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/marketplace/MarketPlace.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/marketplace/MarketPlace.java new file mode 100755 index 0000000000..6ad6139272 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/marketplace/MarketPlace.java @@ -0,0 +1,82 @@ +package com.salesmanager.core.model.catalog.marketplace; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.Embedded; + +import com.salesmanager.core.model.catalog.catalog.Catalog; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + +/** + * A marketplace is the main grouping for the state of product presentation. + * MarketPlace belongs to a main MerchantStore + * A MerchantStore can have a single MarketPlace + * A MarketPlace allows to determine the main MerchantStore allowing determination of content + * and configurations of a given MarketPlace. A MarketPlace has a list of Catalog created by each MerchantStore + * Each Catalog contains a list of Product. A MarketPlace has also a list of Category that merchant cannot change. + * Only the MarketPlace can decide which category are shown and which catalog is part of product offering + * @author c.samson + * + */ +public class MarketPlace extends SalesManagerEntity implements Auditable { + + + /** + * + */ + private static final long serialVersionUID = 1L; + + private MerchantStore store; + + private Long id; + + private String code; + + private Set catalogs = new HashSet(); + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection audit) { + this.auditSection = auditSection; + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public MerchantStore getStore() { + return store; + } + + public void setStore(MerchantStore store) { + this.store = store; + } + + + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/Product.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/Product.java new file mode 100755 index 0000000000..daac44370e --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/Product.java @@ -0,0 +1,556 @@ +package com.salesmanager.core.model.catalog.product; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.UniqueConstraint; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Pattern; + +import org.hibernate.annotations.Cascade; + +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.description.ProductDescription; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.catalog.product.relationship.ProductRelationship; +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.tax.taxclass.TaxClass; + + +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "PRODUCT", uniqueConstraints= +@UniqueConstraint(columnNames = {"MERCHANT_ID", "SKU"})) +public class Product extends SalesManagerEntity implements Auditable { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "PRODUCT_ID", unique=true, nullable=false) + @TableGenerator( + name = "TABLE_GEN", + table = "SM_SEQUENCER", + pkColumnName = "SEQ_NAME", + valueColumnName = "SEQ_COUNT", + pkColumnValue = "PRODUCT_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "product") + private Set descriptions = new HashSet(); + + /** + * Inventory + */ + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="product") + private Set availabilities = new HashSet(); + + /** + * Attributes of a product + * Decorates the product with additional properties + */ + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "product") + private Set attributes = new HashSet(); + + /** + * Default product images + */ + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE, mappedBy = "product")//cascade is set to remove because product save requires logic to create physical image first and then save the image id in the database, cannot be done in cascade + private Set images = new HashSet(); + + /** + * Related items / product groups + */ + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "product") + private Set relationships = new HashSet(); + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore merchantStore; + + /** + * Product to category + */ + @ManyToMany(fetch=FetchType.LAZY, cascade = {CascadeType.REFRESH}) + @JoinTable(name = "PRODUCT_CATEGORY", joinColumns = { + @JoinColumn(name = "PRODUCT_ID", nullable = false, updatable = false) } + , + inverseJoinColumns = { @JoinColumn(name = "CATEGORY_ID", + nullable = false, updatable = false) } + ) + @Cascade({ + org.hibernate.annotations.CascadeType.DETACH, + org.hibernate.annotations.CascadeType.LOCK, + org.hibernate.annotations.CascadeType.REFRESH, + org.hibernate.annotations.CascadeType.REPLICATE + + }) + private Set categories = new HashSet(); + + /** + * Product variants + * Decorates the product with variants + * + */ + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "product") + private Set variants = new HashSet(); + + @Column(name="DATE_AVAILABLE") + @Temporal(TemporalType.TIMESTAMP) + private Date dateAvailable = new Date(); + + + @Column(name = "AVAILABLE") + private boolean available = true; + + + @Column(name = "PREORDER") + private boolean preOrder = false; + + + @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.REFRESH}) + @JoinColumn(name="MANUFACTURER_ID", nullable=true) + private Manufacturer manufacturer; + + @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.REFRESH}) + @JoinColumn(name="PRODUCT_TYPE_ID", nullable=true) + private ProductType type; + + @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.REFRESH}) + @JoinColumn(name="TAX_CLASS_ID", nullable=true) + private TaxClass taxClass; + + @Column(name = "PRODUCT_VIRTUAL") + private boolean productVirtual = false; + + @Column(name = "PRODUCT_SHIP") + private boolean productShipeable = false; + + @Column(name = "PRODUCT_FREE") + private boolean productIsFree; + + @Column(name = "PRODUCT_LENGTH") + private BigDecimal productLength; + + @Column(name = "PRODUCT_WIDTH") + private BigDecimal productWidth; + + @Column(name = "PRODUCT_HEIGHT") + private BigDecimal productHeight; + + @Column(name = "PRODUCT_WEIGHT") + private BigDecimal productWeight; + + @Column(name = "REVIEW_AVG") + private BigDecimal productReviewAvg; + + @Column(name = "REVIEW_COUNT") + private Integer productReviewCount; + + @Column(name = "QUANTITY_ORDERED") + private Integer productOrdered; + + @Column(name = "SORT_ORDER") + private Integer sortOrder = new Integer(0); + + @NotEmpty + @Pattern(regexp="^[a-zA-Z0-9_]*$") + @Column(name = "SKU") + private String sku; + + /** + * External system reference SKU/ID + */ + @Column(name = "REF_SKU") + private String refSku; + + @Column(name="COND", nullable = true) + private ProductCondition condition; + + /** + * RENTAL ADDITIONAL FIELDS + */ + + @Column(name="RENTAL_STATUS", nullable = true) + private RentalStatus rentalStatus; + + + @Column(name="RENTAL_DURATION", nullable = true) + private Integer rentalDuration; + + @Column(name="RENTAL_PERIOD", nullable = true) + private Integer rentalPeriod; + + + public Integer getRentalPeriod() { + return rentalPeriod; + } + + public void setRentalPeriod(Integer rentalPeriod) { + this.rentalPeriod = rentalPeriod; + } + + public Integer getRentalDuration() { + return rentalDuration; + } + + public void setRentalDuration(Integer rentalDuration) { + this.rentalDuration = rentalDuration; + } + + /** + * End rental fields + */ + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="CUSTOMER_ID", nullable=true) + private Customer owner; + + public Product() { + } + + @Override + public Long getId() { + return this.id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection auditSection) { + this.auditSection = auditSection; + } + + + public boolean isProductVirtual() { + return productVirtual; + } + + + + public BigDecimal getProductLength() { + return productLength; + } + + public void setProductLength(BigDecimal productLength) { + this.productLength = productLength; + } + + public BigDecimal getProductWidth() { + return productWidth; + } + + public void setProductWidth(BigDecimal productWidth) { + this.productWidth = productWidth; + } + + public BigDecimal getProductHeight() { + return productHeight; + } + + public void setProductHeight(BigDecimal productHeight) { + this.productHeight = productHeight; + } + + public BigDecimal getProductWeight() { + return productWeight; + } + + public void setProductWeight(BigDecimal productWeight) { + this.productWeight = productWeight; + } + + public BigDecimal getProductReviewAvg() { + return productReviewAvg; + } + + public void setProductReviewAvg(BigDecimal productReviewAvg) { + this.productReviewAvg = productReviewAvg; + } + + public Integer getProductReviewCount() { + return productReviewCount; + } + + public void setProductReviewCount(Integer productReviewCount) { + this.productReviewCount = productReviewCount; + } + + + public Integer getProductOrdered() { + return productOrdered; + } + + public void setProductOrdered(Integer productOrdered) { + this.productOrdered = productOrdered; + } + + public String getSku() { + return sku; + } + + public void setSku(String sku) { + this.sku = sku; + } + + public Set getDescriptions() { + return descriptions; + } + + public void setDescriptions(Set descriptions) { + this.descriptions = descriptions; + } + + + public boolean getProductVirtual() { + return productVirtual; + } + + public void setProductVirtual(boolean productVirtual) { + this.productVirtual = productVirtual; + } + + public boolean getProductIsFree() { + return productIsFree; + } + + public void setProductIsFree(boolean productIsFree) { + this.productIsFree = productIsFree; + } + + + + public Set getAttributes() { + return attributes; + } + + public void setAttributes(Set attributes) { + this.attributes = attributes; + } + + + + public Manufacturer getManufacturer() { + return manufacturer; + } + + public void setManufacturer(Manufacturer manufacturer) { + this.manufacturer = manufacturer; + } + + public ProductType getType() { + return type; + } + + public void setType(ProductType type) { + this.type = type; + } + + + + public Set getAvailabilities() { + return availabilities; + } + + public void setAvailabilities(Set availabilities) { + this.availabilities = availabilities; + } + + public TaxClass getTaxClass() { + return taxClass; + } + + public void setTaxClass(TaxClass taxClass) { + this.taxClass = taxClass; + } + + public Set getImages() { + return images; + } + + public void setImages(Set images) { + this.images = images; + } + + public Set getRelationships() { + return relationships; + } + + public void setRelationships(Set relationships) { + this.relationships = relationships; + } + + + public Set getCategories() { + return categories; + } + + public void setCategories(Set categories) { + this.categories = categories; + } + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + + + public Date getDateAvailable() { + return dateAvailable; + } + + public void setDateAvailable(Date dateAvailable) { + this.dateAvailable = dateAvailable; + } + + public void setSortOrder(Integer sortOrder) { + this.sortOrder = sortOrder; + } + + public Integer getSortOrder() { + return sortOrder; + } + + + + public void setAvailable(Boolean available) { + this.available = available; + } + + public boolean isAvailable() { + return available; + } + + public boolean isProductShipeable() { + return productShipeable; + } + + public void setProductShipeable(Boolean productShipeable) { + this.productShipeable = productShipeable; + } + + + public ProductDescription getProductDescription() { + if(this.getDescriptions()!=null && this.getDescriptions().size()>0) { + return this.getDescriptions().iterator().next(); + } + return null; + } + + public ProductImage getProductImage() { + ProductImage productImage = null; + if(this.getImages()!=null && this.getImages().size()>0) { + for(ProductImage image : this.getImages()) { + productImage = image; + if(productImage.isDefaultImage()) { + break; + } + } + } + return productImage; + } + + public boolean isPreOrder() { + return preOrder; + } + + public void setPreOrder(boolean preOrder) { + this.preOrder = preOrder; + } + + public String getRefSku() { + return refSku; + } + + public void setRefSku(String refSku) { + this.refSku = refSku; + } + + public ProductCondition getCondition() { + return condition; + } + + public void setCondition(ProductCondition condition) { + this.condition = condition; + } + + public RentalStatus getRentalStatus() { + return rentalStatus; + } + + public void setRentalStatus(RentalStatus rentalStatus) { + this.rentalStatus = rentalStatus; + } + + public Customer getOwner() { + return owner; + } + + public void setOwner(Customer owner) { + this.owner = owner; + } + + public Set getVariants() { + return variants; + } + + public void setVariants(Set variants) { + this.variants = variants; + } + + public void setAvailable(boolean available) { + this.available = available; + } + + public void setProductShipeable(boolean productShipeable) { + this.productShipeable = productShipeable; + } + + + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/ProductCondition.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/ProductCondition.java new file mode 100755 index 0000000000..b12f691afa --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/ProductCondition.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.catalog.product; + +public enum ProductCondition { + + NEW, USED + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/ProductCriteria.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/ProductCriteria.java new file mode 100755 index 0000000000..109a003a9a --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/ProductCriteria.java @@ -0,0 +1,151 @@ +package com.salesmanager.core.model.catalog.product; + +import java.util.List; + +import com.salesmanager.core.model.catalog.product.attribute.AttributeCriteria; +import com.salesmanager.core.model.common.Criteria; + +public class ProductCriteria extends Criteria { + + public static final String ORIGIN_SHOP = "shop"; + public static final String ORIGIN_ADMIN = "admin"; + + private String productName; + private List attributeCriteria; + private String origin = ORIGIN_SHOP; + + + private Boolean available = null; + + private List categoryIds; + private List availabilities; + private List productIds; + private List optionValueIds; + private String sku; + + //V2 + private List optionValueCodes; + private String option; + + private String status; + + private Long manufacturerId = null; + + private Long ownerId = null; + + public String getProductName() { + return productName; + } + + public void setProductName(String productName) { + this.productName = productName; + } + + + public List getCategoryIds() { + return categoryIds; + } + + public void setCategoryIds(List categoryIds) { + this.categoryIds = categoryIds; + } + + public List getAvailabilities() { + return availabilities; + } + + public void setAvailabilities(List availabilities) { + this.availabilities = availabilities; + } + + public Boolean getAvailable() { + return available; + } + + public void setAvailable(Boolean available) { + this.available = available; + } + + public void setAttributeCriteria(List attributeCriteria) { + this.attributeCriteria = attributeCriteria; + } + + public List getAttributeCriteria() { + return attributeCriteria; + } + + public void setProductIds(List productIds) { + this.productIds = productIds; + } + + public List getProductIds() { + return productIds; + } + + public void setManufacturerId(Long manufacturerId) { + this.manufacturerId = manufacturerId; + } + + public Long getManufacturerId() { + return manufacturerId; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public Long getOwnerId() { + return ownerId; + } + + public void setOwnerId(Long ownerId) { + this.ownerId = ownerId; + } + + public List getOptionValueIds() { + return optionValueIds; + } + + public void setOptionValueIds(List optionValueIds) { + this.optionValueIds = optionValueIds; + } + + public String getOrigin() { + return origin; + } + + public void setOrigin(String origin) { + this.origin = origin; + } + + public List getOptionValueCodes() { + return optionValueCodes; + } + + public void setOptionValueCodes(List optionValueCodes) { + this.optionValueCodes = optionValueCodes; + } + + public String getOption() { + return option; + } + + public void setOption(String option) { + this.option = option; + } + + public String getSku() { + return sku; + } + + public void setSku(String sku) { + this.sku = sku; + } + + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/ProductDimensions.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/ProductDimensions.java new file mode 100644 index 0000000000..04fe0edfac --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/ProductDimensions.java @@ -0,0 +1,47 @@ +package com.salesmanager.core.model.catalog.product; + +import java.math.BigDecimal; +import javax.persistence.Column; +import javax.persistence.Embeddable; + +@Embeddable +public class ProductDimensions { + + + @Column(name = "LENGTH") + private BigDecimal length; + + @Column(name = "WIDTH") + private BigDecimal width; + + @Column(name = "HEIGHT") + private BigDecimal height; + + @Column(name = "WEIGHT") + private BigDecimal weight; + + public BigDecimal getLength() { + return length; + } + + public void setLength(BigDecimal length) { + this.length = length; + } + + public BigDecimal getWidth() { + return width; + } + + public void setWidth(BigDecimal width) { + this.width = width; + } + + public BigDecimal getWeight() { + return weight; + } + + public void setWeight(BigDecimal weight) { + this.weight = weight; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/ProductList.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/ProductList.java new file mode 100755 index 0000000000..946bba5d2e --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/ProductList.java @@ -0,0 +1,25 @@ +package com.salesmanager.core.model.catalog.product; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.core.model.common.EntityList; + +public class ProductList extends EntityList { + + + + /** + * + */ + private static final long serialVersionUID = 7267292601646149482L; + private List products = new ArrayList(); + public List getProducts() { + return products; + } + public void setProducts(List products) { + this.products = products; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/RentalStatus.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/RentalStatus.java new file mode 100755 index 0000000000..5e5ed3c821 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/RentalStatus.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.catalog.product; + +public enum RentalStatus { + + RENTED, AVAILABLE + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/AttributeCriteria.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/AttributeCriteria.java new file mode 100755 index 0000000000..67bc0dd66c --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/AttributeCriteria.java @@ -0,0 +1,26 @@ +package com.salesmanager.core.model.catalog.product.attribute; + +import java.io.Serializable; + +public class AttributeCriteria implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String attributeCode; + private String attributeValue; + public void setAttributeCode(String attributeCode) { + this.attributeCode = attributeCode; + } + public String getAttributeCode() { + return attributeCode; + } + public void setAttributeValue(String attributeValue) { + this.attributeValue = attributeValue; + } + public String getAttributeValue() { + return attributeValue; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/Optionable.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/Optionable.java new file mode 100644 index 0000000000..f2d19d1aee --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/Optionable.java @@ -0,0 +1,11 @@ +package com.salesmanager.core.model.catalog.product.attribute; + +public interface Optionable { + + ProductOption getProductOption(); + void setProductOption(ProductOption option); + + ProductOptionValue getProductOptionValue(); + void setProductOptionValue(ProductOptionValue optionValue); + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductAttribute.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductAttribute.java new file mode 100755 index 0000000000..1b860333aa --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductAttribute.java @@ -0,0 +1,250 @@ +package com.salesmanager.core.model.catalog.product.attribute; + +import java.math.BigDecimal; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; +import javax.persistence.Index; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.generic.SalesManagerEntity; + +@Entity +@Table(name="PRODUCT_ATTRIBUTE", + indexes = @Index(columnList = "PRODUCT_ID"), + uniqueConstraints={ + @UniqueConstraint(columnNames={ + "OPTION_ID", + "OPTION_VALUE_ID", + "PRODUCT_ID" + }) + } +) + +/** + * Attribute Size - Small and product + * @author carlsamson + * + */ + +public class ProductAttribute extends SalesManagerEntity implements Optionable { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "PRODUCT_ATTRIBUTE_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "PRODUCT_ATTR_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + + @Column(name="PRODUCT_ATRIBUTE_PRICE") + private BigDecimal productAttributePrice; + + + @Column(name="PRODUCT_ATTRIBUTE_SORT_ORD") + private Integer productOptionSortOrder; + + @Column(name="PRODUCT_ATTRIBUTE_FREE") + private boolean productAttributeIsFree; + + + @Column(name="PRODUCT_ATTRIBUTE_WEIGHT") + private BigDecimal productAttributeWeight; + + @Column(name="PRODUCT_ATTRIBUTE_DEFAULT") + private boolean attributeDefault=false; + + @Column(name="PRODUCT_ATTRIBUTE_REQUIRED") + private boolean attributeRequired=false; + + /** + * a read only attribute is considered as a core attribute addition + */ + @Column(name="PRODUCT_ATTRIBUTE_FOR_DISP") + private boolean attributeDisplayOnly=false; + + + @Column(name="PRODUCT_ATTRIBUTE_DISCOUNTED") + private boolean attributeDiscounted=false; + + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="OPTION_ID", nullable=false) + private ProductOption productOption; + + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="OPTION_VALUE_ID", nullable=false) + private ProductOptionValue productOptionValue; + + + /** + * This transient object property + * is a utility used only to submit from a free text + */ + @Transient + private String attributePrice = "0"; + + + /** + * This transient object property + * is a utility used only to submit from a free text + */ + @Transient + private String attributeSortOrder = "0"; + + + + /** + * This transient object property + * is a utility used only to submit from a free text + */ + @Transient + private String attributeAdditionalWeight = "0"; + + public String getAttributePrice() { + return attributePrice; + } + + public void setAttributePrice(String attributePrice) { + this.attributePrice = attributePrice; + } + + + @ManyToOne(targetEntity = Product.class) + @JoinColumn(name = "PRODUCT_ID", nullable = false) + private Product product; + + public ProductAttribute() { + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + + + public Integer getProductOptionSortOrder() { + return productOptionSortOrder; + } + + public void setProductOptionSortOrder(Integer productOptionSortOrder) { + this.productOptionSortOrder = productOptionSortOrder; + } + + public boolean getProductAttributeIsFree() { + return productAttributeIsFree; + } + + public void setProductAttributeIsFree(boolean productAttributeIsFree) { + this.productAttributeIsFree = productAttributeIsFree; + } + + public BigDecimal getProductAttributeWeight() { + return productAttributeWeight; + } + + public void setProductAttributeWeight(BigDecimal productAttributeWeight) { + this.productAttributeWeight = productAttributeWeight; + } + + public boolean getAttributeDefault() { + return attributeDefault; + } + + public void setAttributeDefault(boolean attributeDefault) { + this.attributeDefault = attributeDefault; + } + + public boolean getAttributeRequired() { + return attributeRequired; + } + + public void setAttributeRequired(boolean attributeRequired) { + this.attributeRequired = attributeRequired; + } + + public boolean getAttributeDisplayOnly() { + return attributeDisplayOnly; + } + + public void setAttributeDisplayOnly(boolean attributeDisplayOnly) { + this.attributeDisplayOnly = attributeDisplayOnly; + } + + public boolean getAttributeDiscounted() { + return attributeDiscounted; + } + + public void setAttributeDiscounted(boolean attributeDiscounted) { + this.attributeDiscounted = attributeDiscounted; + } + + public ProductOption getProductOption() { + return productOption; + } + + public void setProductOption(ProductOption productOption) { + this.productOption = productOption; + } + + public ProductOptionValue getProductOptionValue() { + return productOptionValue; + } + + public void setProductOptionValue(ProductOptionValue productOptionValue) { + this.productOptionValue = productOptionValue; + } + + public Product getProduct() { + return product; + } + + public void setProduct(Product product) { + this.product = product; + } + + + public String getAttributeSortOrder() { + return attributeSortOrder; + } + + public void setAttributeSortOrder(String attributeSortOrder) { + this.attributeSortOrder = attributeSortOrder; + } + + public String getAttributeAdditionalWeight() { + return attributeAdditionalWeight; + } + + public void setAttributeAdditionalWeight(String attributeAdditionalWeight) { + this.attributeAdditionalWeight = attributeAdditionalWeight; + } + + public BigDecimal getProductAttributePrice() { + return productAttributePrice; + } + + public void setProductAttributePrice(BigDecimal productAttributePrice) { + this.productAttributePrice = productAttributePrice; + } + + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOption.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOption.java new file mode 100755 index 0000000000..f8748fdb3e --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOption.java @@ -0,0 +1,149 @@ +package com.salesmanager.core.model.catalog.product.attribute; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Pattern; + +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + + +@Entity +@Table(name="PRODUCT_OPTION", + + indexes = { @Index(name="PRD_OPTION_CODE_IDX", columnList = "PRODUCT_OPTION_CODE")}, + uniqueConstraints=@UniqueConstraint(columnNames = {"MERCHANT_ID", "PRODUCT_OPTION_CODE"})) + +public class ProductOption extends SalesManagerEntity { + private static final long serialVersionUID = 1L; + + @Id + @Column(name="PRODUCT_OPTION_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "PRODUCT_OPTION_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Column(name="PRODUCT_OPTION_SORT_ORD") + private Integer productOptionSortOrder; + + @Column(name="PRODUCT_OPTION_TYPE", length=10) + private String productOptionType; + + + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "productOption") + private Set descriptions = new HashSet(); + + @Transient + private List descriptionsList = new ArrayList(); + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore merchantStore; + + @Column(name="PRODUCT_OPTION_READ") + private boolean readOnly; + + @NotEmpty + @Pattern(regexp="^[a-zA-Z0-9_]*$") + @Column(name="PRODUCT_OPTION_CODE") + private String code; + + public ProductOption() { + } + + public Integer getProductOptionSortOrder() { + return productOptionSortOrder; + } + + public void setProductOptionSortOrder(Integer productOptionSortOrder) { + this.productOptionSortOrder = productOptionSortOrder; + } + + public String getProductOptionType() { + return productOptionType; + } + + public void setProductOptionType(String productOptionType) { + this.productOptionType = productOptionType; + } + + public Set getDescriptions() { + return descriptions; + } + + public void setDescriptions(Set descriptions) { + this.descriptions = descriptions; + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public void setDescriptionsList(List descriptionsList) { + this.descriptionsList = descriptionsList; + } + + public List getDescriptionsList() { + return descriptionsList; + } + + + public List getDescriptionsSettoList() { + if(descriptionsList==null || descriptionsList.size()==0) { + descriptionsList = new ArrayList(this.getDescriptions()); + } + return descriptionsList; + + } + + public void setCode(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + + public void setReadOnly(boolean readOnly) { + this.readOnly = readOnly; + } + + public boolean isReadOnly() { + return readOnly; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOptionDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOptionDescription.java new file mode 100755 index 0000000000..089f0ac8f2 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOptionDescription.java @@ -0,0 +1,51 @@ +package com.salesmanager.core.model.catalog.product.attribute; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.description.Description; + +@Entity + +@Table(name = "PRODUCT_OPTION_DESC", +uniqueConstraints = {@UniqueConstraint(columnNames = { "PRODUCT_OPTION_ID", "LANGUAGE_ID" })} + +) + +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "product_option_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +public class ProductOptionDescription extends Description { + private static final long serialVersionUID = 1L; + + @JsonIgnore + @ManyToOne(targetEntity = ProductOption.class) + @JoinColumn(name = "PRODUCT_OPTION_ID", nullable = false) + private ProductOption productOption; + + @Column(name="PRODUCT_OPTION_COMMENT", length=4000) + private String productOptionComment; + + public ProductOptionDescription() { + } + + public String getProductOptionComment() { + return productOptionComment; + } + public void setProductOptionComment(String productOptionComment) { + this.productOptionComment = productOptionComment; + } + + public ProductOption getProductOption() { + return productOption; + } + + public void setProductOption(ProductOption productOption) { + this.productOption = productOption; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOptionSet.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOptionSet.java new file mode 100644 index 0000000000..54dd4fe923 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOptionSet.java @@ -0,0 +1,127 @@ +package com.salesmanager.core.model.catalog.product.attribute; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Pattern; + +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + +/** + * Create a list of option and option value in order to accelerate and + * prepare product attribute creation + * @author carlsamson + * + */ +@Entity +@Table(name="PRODUCT_OPTION_SET", +uniqueConstraints={ + @UniqueConstraint(columnNames={ + "MERCHANT_ID", + "PRODUCT_OPTION_SET_CODE" + }) + } +) +public class ProductOptionSet extends SalesManagerEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + @Column(name="PRODUCT_OPTION_SET_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "PRODUCT_OPT_SET_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @NotEmpty + @Pattern(regexp="^[a-zA-Z0-9_]*$") + @Column(name="PRODUCT_OPTION_SET_CODE") + private String code; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="PRODUCT_OPTION_ID", nullable=false) + private ProductOption option; + + @ManyToMany(fetch = FetchType.LAZY, targetEntity=ProductOptionValue.class) + @JoinTable(name = "PRODUCT_OPT_SET_OPT_VALUE") + private List values = new ArrayList(); + + @ManyToMany(fetch = FetchType.LAZY, targetEntity=ProductType.class) + @JoinTable(name = "PRODUCT_OPT_SET_PRD_TYPE") + private Set productTypes = new HashSet(); + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore store; + + @Column(name="PRODUCT_OPTION_SET_DISP") + private boolean optionDisplayOnly = false; + + + public ProductOption getOption() { + return option; + } + public void setOption(ProductOption option) { + this.option = option; + } + public List getValues() { + return values; + } + public void setValues(List values) { + this.values = values; + } + public MerchantStore getStore() { + return store; + } + public void setStore(MerchantStore store) { + this.store = store; + } + @Override + public Long getId() { + return this.id; + } + @Override + public void setId(Long id) { + this.id = id; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public boolean isOptionDisplayOnly() { + return optionDisplayOnly; + } + public void setOptionDisplayOnly(boolean optionDisplayOnly) { + this.optionDisplayOnly = optionDisplayOnly; + } + + public Set getProductTypes() { + return productTypes; + } + public void setProductTypes(Set productTypes) { + this.productTypes = productTypes; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOptionType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOptionType.java new file mode 100755 index 0000000000..a24cecfde6 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOptionType.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.catalog.product.attribute; + +public enum ProductOptionType { + + Text, Radio, Select, Checkbox + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOptionValue.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOptionValue.java new file mode 100755 index 0000000000..43aa522e90 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOptionValue.java @@ -0,0 +1,160 @@ +package com.salesmanager.core.model.catalog.product.attribute; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Pattern; + +import org.springframework.web.multipart.MultipartFile; + +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + + +@Entity +@Table(name="PRODUCT_OPTION_VALUE", +indexes = { @Index(name="PRD_OPTION_VAL_CODE_IDX", columnList = "PRODUCT_OPTION_VAL_CODE")}, +uniqueConstraints= + @UniqueConstraint(columnNames = {"MERCHANT_ID", "PRODUCT_OPTION_VAL_CODE"})) +public class ProductOptionValue extends SalesManagerEntity { + private static final long serialVersionUID = 1L; + + @Id + @Column(name="PRODUCT_OPTION_VALUE_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "PRODUCT_OPT_VAL_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Column(name="PRODUCT_OPT_VAL_SORT_ORD") + private Integer productOptionValueSortOrder; + + @Column(name="PRODUCT_OPT_VAL_IMAGE") + private String productOptionValueImage; + + @Column(name="PRODUCT_OPT_FOR_DISP") + private boolean productOptionDisplayOnly=false; + + @NotEmpty + @Pattern(regexp="^[a-zA-Z0-9_]*$") + @Column(name="PRODUCT_OPTION_VAL_CODE") + private String code; + + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "productOptionValue") + private Set descriptions = new HashSet(); + + @Transient + private MultipartFile image = null; + + public MultipartFile getImage() { + return image; + } + + public void setImage(MultipartFile image) { + this.image = image; + } + + @Transient + private List descriptionsList = new ArrayList(); + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore merchantStore; + + public ProductOptionValue() { + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public Integer getProductOptionValueSortOrder() { + return productOptionValueSortOrder; + } + + public void setProductOptionValueSortOrder(Integer productOptionValueSortOrder) { + this.productOptionValueSortOrder = productOptionValueSortOrder; + } + + public String getProductOptionValueImage() { + return productOptionValueImage; + } + + public void setProductOptionValueImage(String productOptionValueImage) { + this.productOptionValueImage = productOptionValueImage; + } + + public Set getDescriptions() { + return descriptions; + } + + public void setDescriptions(Set descriptions) { + this.descriptions = descriptions; + } + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public void setDescriptionsList(List descriptionsList) { + this.descriptionsList = descriptionsList; + } + + public List getDescriptionsList() { + return descriptionsList; + } + + public List getDescriptionsSettoList() { + if(descriptionsList==null || descriptionsList.size()==0) { + descriptionsList = new ArrayList(this.getDescriptions()); + } + return descriptionsList; + } + + public boolean isProductOptionDisplayOnly() { + return productOptionDisplayOnly; + } + + public void setProductOptionDisplayOnly(boolean productOptionDisplayOnly) { + this.productOptionDisplayOnly = productOptionDisplayOnly; + } + + public void setCode(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + + + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOptionValueDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOptionValueDescription.java new file mode 100755 index 0000000000..bd1ae751e4 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/attribute/ProductOptionValueDescription.java @@ -0,0 +1,43 @@ +package com.salesmanager.core.model.catalog.product.attribute; + +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.description.Description; + +@Entity +@Table(name = "PRODUCT_OPTION_VALUE_DESCRIPTION", uniqueConstraints={ + @UniqueConstraint(columnNames={ + "PRODUCT_OPTION_VALUE_ID", + "LANGUAGE_ID" + }) + } +) + +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "product_option_value_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +public class ProductOptionValueDescription extends Description { + private static final long serialVersionUID = 1L; + + @JsonIgnore + @ManyToOne(targetEntity = ProductOptionValue.class) + @JoinColumn(name = "PRODUCT_OPTION_VALUE_ID") + private ProductOptionValue productOptionValue; + + public ProductOptionValueDescription() { + } + + public ProductOptionValue getProductOptionValue() { + return productOptionValue; + } + + public void setProductOptionValue(ProductOptionValue productOptionValue) { + this.productOptionValue = productOptionValue; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/availability/ProductAvailability.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/availability/ProductAvailability.java new file mode 100755 index 0000000000..79a703aad1 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/availability/ProductAvailability.java @@ -0,0 +1,306 @@ +package com.salesmanager.core.model.catalog.product.availability; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.ProductDimensions; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.utils.CloneUtils; + +@Entity +@Table(name = "PRODUCT_AVAILABILITY", +uniqueConstraints= @UniqueConstraint(columnNames = {"MERCHANT_ID", "PRODUCT_ID", "PRODUCT_VARIANT", "REGION_VARIANT"}), +indexes = + { + @Index(name="PRD_AVAIL_STORE_PRD_IDX", columnList = "PRODUCT_ID,MERCHANT_ID"), + @Index(name="PRD_AVAIL_PRD_IDX", columnList = "PRODUCT_ID") + } +) + +/** + * Default availability + * + * store + * product id + * + * variant null + * regionVariant null + * + * @author carlsamson + * + */ +public class ProductAvailability extends SalesManagerEntity implements Auditable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @Id + @Column(name = "PRODUCT_AVAIL_ID", unique = true, nullable = false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "PRODUCT_AVAIL_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @JsonIgnore + @ManyToOne(targetEntity = Product.class) + @JoinColumn(name = "PRODUCT_ID", nullable = false) + private Product product; + + /** Specific retailer store **/ + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "MERCHANT_ID", nullable = true) + private MerchantStore merchantStore; + + /** + * This describes the availability of a product variant + */ + @ManyToOne(targetEntity = ProductVariant.class) + @JoinColumn(name = "PRODUCT_VARIANT", nullable = true) + private ProductVariant productVariant; + + @Pattern(regexp="^[a-zA-Z0-9_]*$") + @Column(name = "SKU", nullable = true) + private String sku; + + @Embedded + private ProductDimensions dimensions; + + @NotNull + @Column(name = "QUANTITY") + private Integer productQuantity = 0; + + @Temporal(TemporalType.DATE) + @Column(name = "DATE_AVAILABLE") + private Date productDateAvailable; + + @Column(name = "REGION") + private String region = SchemaConstant.ALL_REGIONS; + + @Column(name = "REGION_VARIANT") + private String regionVariant; + + @Column(name = "OWNER") + private String owner; + + @Column(name = "STATUS") + private boolean productStatus = true; //can be used as flag for variant can be purchase or not + + @Column(name = "FREE_SHIPPING") + private boolean productIsAlwaysFreeShipping; + + @Column(name = "AVAILABLE") + private Boolean available; + + @Column(name = "QUANTITY_ORD_MIN") + private Integer productQuantityOrderMin = 0; + + @Column(name = "QUANTITY_ORD_MAX") + private Integer productQuantityOrderMax = 0; + + @OneToMany(fetch = FetchType.LAZY, mappedBy = "productAvailability", cascade = CascadeType.ALL) + private Set prices = new HashSet(); + + + @Transient + public ProductPrice defaultPrice() { + for (ProductPrice price : prices) { + if (price.isDefaultPrice()) { + return price; + } + } + return new ProductPrice(); + } + + public ProductAvailability() { + } + + public ProductAvailability(Product product, MerchantStore store) { + this.product = product; + this.merchantStore = store; + } + + public Integer getProductQuantity() { + return productQuantity; + } + + public void setProductQuantity(Integer productQuantity) { + this.productQuantity = productQuantity; + } + + public Date getProductDateAvailable() { + return CloneUtils.clone(productDateAvailable); + } + + public void setProductDateAvailable(Date productDateAvailable) { + this.productDateAvailable = CloneUtils.clone(productDateAvailable); + } + + public String getRegion() { + return region; + } + + public void setRegion(String region) { + this.region = region; + } + + public String getRegionVariant() { + return regionVariant; + } + + public void setRegionVariant(String regionVariant) { + this.regionVariant = regionVariant; + } + + public boolean getProductStatus() { + return productStatus; + } + + public void setProductStatus(boolean productStatus) { + this.productStatus = productStatus; + } + + public boolean getProductIsAlwaysFreeShipping() { + return productIsAlwaysFreeShipping; + } + + public void setProductIsAlwaysFreeShipping(boolean productIsAlwaysFreeShipping) { + this.productIsAlwaysFreeShipping = productIsAlwaysFreeShipping; + } + + public Integer getProductQuantityOrderMin() { + return productQuantityOrderMin; + } + + public void setProductQuantityOrderMin(Integer productQuantityOrderMin) { + this.productQuantityOrderMin = productQuantityOrderMin; + } + + public Integer getProductQuantityOrderMax() { + return productQuantityOrderMax; + } + + public void setProductQuantityOrderMax(Integer productQuantityOrderMax) { + this.productQuantityOrderMax = productQuantityOrderMax; + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public Product getProduct() { + return product; + } + + public void setProduct(Product product) { + this.product = product; + } + + public Set getPrices() { + return prices; + } + + public void setPrices(Set prices) { + this.prices = prices; + } + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection audit) { + this.auditSection = audit; + + } + + public Boolean getAvailable() { + return available; + } + + public void setAvailable(Boolean available) { + this.available = available; + } + + public String getSku() { + return sku; + } + + public void setSku(String sku) { + this.sku = sku; + } + + public ProductDimensions getDimensions() { + return dimensions; + } + + public void setDimensions(ProductDimensions dimensions) { + this.dimensions = dimensions; + } + + public ProductVariant getProductVariant() { + return productVariant; + } + + public void setProductVariant(ProductVariant productVariant) { + this.productVariant = productVariant; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/description/ProductDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/description/ProductDescription.java new file mode 100755 index 0000000000..7e070235a8 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/description/ProductDescription.java @@ -0,0 +1,108 @@ +package com.salesmanager.core.model.catalog.product.description; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.common.description.Description; + +@Entity +@Table(name = "PRODUCT_DESCRIPTION", + uniqueConstraints = {@UniqueConstraint(columnNames = { "PRODUCT_ID", "LANGUAGE_ID" })}, + indexes = {@Index(name = "PRODUCT_DESCRIPTION_SEF_URL", columnList = "SEF_URL")}) + +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "product_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +public class ProductDescription extends Description { + private static final long serialVersionUID = 1L; + + @JsonIgnore + @ManyToOne(targetEntity = Product.class) + @JoinColumn(name = "PRODUCT_ID", nullable = false) + private Product product; + + @Column(name = "PRODUCT_HIGHLIGHT") + private String productHighlight; + + @Column(name = "DOWNLOAD_LNK") + private String productExternalDl; + + @Column(name = "SEF_URL") + private String seUrl; + + @Column(name = "META_TITLE") + private String metatagTitle; + + @Column(name = "META_KEYWORDS") + private String metatagKeywords; + + @Column(name = "META_DESCRIPTION") + private String metatagDescription; + + public ProductDescription() { + } + + public String getProductHighlight() { + return productHighlight; + } + + public void setProductHighlight(String productHighlight) { + this.productHighlight = productHighlight; + } + + public String getProductExternalDl() { + return productExternalDl; + } + + public void setProductExternalDl(String productExternalDl) { + this.productExternalDl = productExternalDl; + } + + public String getSeUrl() { + return seUrl; + } + + public void setSeUrl(String seUrl) { + this.seUrl = seUrl; + } + + public String getMetatagTitle() { + return metatagTitle; + } + + public void setMetatagTitle(String metatagTitle) { + this.metatagTitle = metatagTitle; + } + + public String getMetatagKeywords() { + return metatagKeywords; + } + + public void setMetatagKeywords(String metatagKeywords) { + this.metatagKeywords = metatagKeywords; + } + + public String getMetatagDescription() { + return metatagDescription; + } + + public void setMetatagDescription(String metatagDescription) { + this.metatagDescription = metatagDescription; + } + + public Product getProduct() { + return product; + } + + public void setProduct(Product product) { + this.product = product; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/file/DigitalProduct.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/file/DigitalProduct.java new file mode 100755 index 0000000000..b98bf78ed3 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/file/DigitalProduct.java @@ -0,0 +1,76 @@ +package com.salesmanager.core.model.catalog.product.file; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.generic.SalesManagerEntity; + + +/** + * Representation of a digital product + * @author csamson777 + * + */ +@Entity +@Table(name = "PRODUCT_DIGITAL", uniqueConstraints= + @UniqueConstraint(columnNames = {"PRODUCT_ID", "FILE_NAME"})) +public class DigitalProduct extends SalesManagerEntity { + + + private static final long serialVersionUID = 1L; + + + @Id + @Column(name = "PRODUCT_DIGITAL_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "PRODUCT_DGT_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + + @ManyToOne(targetEntity = Product.class) + @JoinColumn(name = "PRODUCT_ID", nullable = false) + private Product product; + + + @Column(name="FILE_NAME",nullable=false) + private String productFileName; + + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public String getProductFileName() { + return productFileName; + } + + public void setProductFileName(String productFileName) { + this.productFileName = productFileName; + } + + public Product getProduct() { + return product; + } + + public void setProduct(Product product) { + this.product = product; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/file/ProductImageSize.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/file/ProductImageSize.java new file mode 100755 index 0000000000..a3b8b9733d --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/file/ProductImageSize.java @@ -0,0 +1,10 @@ +package com.salesmanager.core.model.catalog.product.file; + +public enum ProductImageSize { + + LARGE, + SMALL + + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/image/ProductImage.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/image/ProductImage.java new file mode 100755 index 0000000000..47a30533b0 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/image/ProductImage.java @@ -0,0 +1,160 @@ +package com.salesmanager.core.model.catalog.product.image; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Transient; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.generic.SalesManagerEntity; + +@Entity +@Table(name = "PRODUCT_IMAGE") +public class ProductImage extends SalesManagerEntity { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "PRODUCT_IMAGE_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "PRODUCT_IMG_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @OneToMany(fetch = FetchType.LAZY, mappedBy = "productImage", cascade = CascadeType.ALL) + private List descriptions = new ArrayList(); + + + @Column(name = "PRODUCT_IMAGE") + private String productImage; + + @Column(name = "DEFAULT_IMAGE") + private boolean defaultImage = true; + + /** + * default to 0 for images managed by the system + */ + @Column(name = "IMAGE_TYPE") + private int imageType; + + /** + * Refers to images not accessible through the system. It may also be a video. + */ + @Column(name = "PRODUCT_IMAGE_URL") + private String productImageUrl; + + + @Column(name = "IMAGE_CROP") + private boolean imageCrop; + + @ManyToOne(targetEntity = Product.class) + @JoinColumn(name = "PRODUCT_ID", nullable = false) + private Product product; + + @Column(name = "SORT_ORDER") + private Integer sortOrder = 0; + + + @Transient + private InputStream image = null; + + //private MultiPartFile image + + public ProductImage(){ + } + + public String getProductImage() { + return productImage; + } + + public void setProductImage(String productImage) { + this.productImage = productImage; + } + + public boolean isDefaultImage() { + return defaultImage; + } + + public void setDefaultImage(boolean defaultImage) { + this.defaultImage = defaultImage; + } + + public Integer getSortOrder() { + return sortOrder; + } + + public void setSortOrder(Integer sortOrder) { + this.sortOrder = sortOrder; + } + + public int getImageType() { + return imageType; + } + + public void setImageType(int imageType) { + this.imageType = imageType; + } + + public boolean isImageCrop() { + return imageCrop; + } + + public void setImageCrop(boolean imageCrop) { + this.imageCrop = imageCrop; + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public Product getProduct() { + return product; + } + + public void setProduct(Product product) { + this.product = product; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + + public List getDescriptions() { + return descriptions; + } + + public InputStream getImage() { + return image; + } + + public void setImage(InputStream image) { + this.image = image; + } + + public String getProductImageUrl() { + return productImageUrl; + } + + public void setProductImageUrl(String productImageUrl) { + this.productImageUrl = productImageUrl; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/image/ProductImageDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/image/ProductImageDescription.java new file mode 100755 index 0000000000..57bd9e761c --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/image/ProductImageDescription.java @@ -0,0 +1,50 @@ +package com.salesmanager.core.model.catalog.product.image; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.description.Description; + +@Entity +@Table(name="PRODUCT_IMAGE_DESCRIPTION", uniqueConstraints={ + @UniqueConstraint(columnNames={ + "PRODUCT_IMAGE_ID", + "LANGUAGE_ID" + }) + } +) +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "product_image_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +public class ProductImageDescription extends Description { + private static final long serialVersionUID = 1L; + + @ManyToOne(targetEntity = ProductImage.class) + @JoinColumn(name = "PRODUCT_IMAGE_ID", nullable = false) + private ProductImage productImage; + + @Column(name="ALT_TAG", length=100) + private String altTag; + + public ProductImage getProductImage() { + return productImage; + } + + public void setProductImage(ProductImage productImage) { + this.productImage = productImage; + } + + public String getAltTag() { + return altTag; + } + + public void setAltTag(String altTag) { + this.altTag = altTag; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/inventory/ProductInventory.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/inventory/ProductInventory.java new file mode 100644 index 0000000000..d2339f512f --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/inventory/ProductInventory.java @@ -0,0 +1,33 @@ +package com.salesmanager.core.model.catalog.product.inventory; + +import java.io.Serializable; + +import com.salesmanager.core.model.catalog.product.price.FinalPrice; + +public class ProductInventory implements Serializable { + + private static final long serialVersionUID = 1L; + + private String sku; + private long quantity; + private FinalPrice price; + public String getSku() { + return sku; + } + public void setSku(String sku) { + this.sku = sku; + } + public long getQuantity() { + return quantity; + } + public void setQuantity(long quantity) { + this.quantity = quantity; + } + public FinalPrice getPrice() { + return price; + } + public void setPrice(FinalPrice price) { + this.price = price; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/manufacturer/Manufacturer.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/manufacturer/Manufacturer.java new file mode 100755 index 0000000000..37aaa0ee69 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/manufacturer/Manufacturer.java @@ -0,0 +1,130 @@ +package com.salesmanager.core.model.catalog.product.manufacturer; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import javax.validation.constraints.NotEmpty; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "MANUFACTURER", uniqueConstraints= +@UniqueConstraint(columnNames = {"MERCHANT_ID", "CODE"}) ) +public class Manufacturer extends SalesManagerEntity implements Auditable { + private static final long serialVersionUID = 1L; + + public static final String DEFAULT_MANUFACTURER = "DEFAULT"; + + @Id + @Column(name = "MANUFACTURER_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "MANUFACT_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @OneToMany(mappedBy = "manufacturer", cascade = CascadeType.ALL , fetch = FetchType.EAGER) + private Set descriptions = new HashSet(); + + @Column(name = "MANUFACTURER_IMAGE") + private String image; + + @Column(name="SORT_ORDER") + private Integer order = new Integer(0); + + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore merchantStore; + + @NotEmpty + @Column(name="CODE", length=100, nullable=false) + private String code; + + public Manufacturer() { + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection auditSection) { + this.auditSection = auditSection; + } + + public String getImage() { + return image; + } + + public void setImage(String image) { + this.image = image; + } + + public Set getDescriptions() { + return descriptions; + } + + public void setDescriptions(Set descriptions) { + this.descriptions = descriptions; + } + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public void setOrder(Integer order) { + this.order = order; + } + + public Integer getOrder() { + return order; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/manufacturer/ManufacturerDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/manufacturer/ManufacturerDescription.java new file mode 100755 index 0000000000..70d8654f0f --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/manufacturer/ManufacturerDescription.java @@ -0,0 +1,78 @@ +package com.salesmanager.core.model.catalog.product.manufacturer; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.description.Description; + +@Entity +@Table(name = "MANUFACTURER_DESCRIPTION", uniqueConstraints={ + @UniqueConstraint(columnNames={ + "MANUFACTURER_ID", + "LANGUAGE_ID" + }) + } +) + +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "manufacturer_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +public class ManufacturerDescription extends Description { + private static final long serialVersionUID = 1L; + + @JsonIgnore + @ManyToOne(targetEntity = Manufacturer.class) + @JoinColumn(name = "MANUFACTURER_ID", nullable = false) + private Manufacturer manufacturer; + + @Column(name = "MANUFACTURERS_URL") + private String url; + + @Column(name = "URL_CLICKED") + private Integer urlClicked; + + @Column(name = "DATE_LAST_CLICK") + private Date dateLastClick; + + public ManufacturerDescription() { + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public Integer getUrlClicked() { + return urlClicked; + } + + public void setUrlClicked(Integer urlClicked) { + this.urlClicked = urlClicked; + } + + public Date getDateLastClick() { + return dateLastClick; + } + + public void setDateLastClick(Date dateLastClick) { + this.dateLastClick = dateLastClick; + } + + public Manufacturer getManufacturer() { + return manufacturer; + } + + public void setManufacturer(Manufacturer manufacturer) { + this.manufacturer = manufacturer; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/price/FinalPrice.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/price/FinalPrice.java new file mode 100755 index 0000000000..2dd89429e9 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/price/FinalPrice.java @@ -0,0 +1,125 @@ +package com.salesmanager.core.model.catalog.product.price; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + * Transient entity used to display + * different price information in the catalogue + * @author Carl Samson + * + */ +public class FinalPrice implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private BigDecimal discountedPrice = null;//final price if a discount is applied + private BigDecimal originalPrice = null;//original price + private BigDecimal finalPrice = null;//final price discount or not + private boolean discounted = false; + private int discountPercent = 0; + private String stringPrice; + private String stringDiscountedPrice; + + private Date discountEndDate = null; + + private boolean defaultPrice; + private ProductPrice productPrice; + List additionalPrices; + + public List getAdditionalPrices() { + return additionalPrices; + } + + public void setAdditionalPrices(List additionalPrices) { + this.additionalPrices = additionalPrices; + } + + public BigDecimal getOriginalPrice() { + return originalPrice; + } + + public void setOriginalPrice(BigDecimal originalPrice) { + this.originalPrice = originalPrice; + } + + + + public int getDiscountPercent() { + return discountPercent; + } + + public void setDiscountPercent(int discountPercent) { + this.discountPercent = discountPercent; + } + + public Date getDiscountEndDate() { + return discountEndDate; + } + + public void setDiscountEndDate(Date discountEndDate) { + this.discountEndDate = discountEndDate; + } + + public boolean isDiscounted() { + return discounted; + } + + public void setDiscounted(boolean discounted) { + this.discounted = discounted; + } + + public void setDiscountedPrice(BigDecimal discountedPrice) { + this.discountedPrice = discountedPrice; + } + + public BigDecimal getDiscountedPrice() { + return discountedPrice; + } + + + public void setFinalPrice(BigDecimal finalPrice) { + this.finalPrice = finalPrice; + } + + public BigDecimal getFinalPrice() { + return finalPrice; + } + + public void setDefaultPrice(boolean defaultPrice) { + this.defaultPrice = defaultPrice; + } + + public boolean isDefaultPrice() { + return defaultPrice; + } + + public void setProductPrice(ProductPrice productPrice) { + this.productPrice = productPrice; + } + + public ProductPrice getProductPrice() { + return productPrice; + } + + public String getStringPrice() { + return stringPrice; + } + + public void setStringPrice(String stringPrice) { + this.stringPrice = stringPrice; + } + + public String getStringDiscountedPrice() { + return stringDiscountedPrice; + } + + public void setStringDiscountedPrice(String stringDiscountedPrice) { + this.stringDiscountedPrice = stringDiscountedPrice; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/price/ProductPrice.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/price/ProductPrice.java new file mode 100755 index 0000000000..ae3730b60d --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/price/ProductPrice.java @@ -0,0 +1,168 @@ +package com.salesmanager.core.model.catalog.product.price; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Pattern; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.utils.CloneUtils; + +@Entity +@Table(name = "PRODUCT_PRICE") +public class ProductPrice extends SalesManagerEntity { + private static final long serialVersionUID = 1L; + + public final static String DEFAULT_PRICE_CODE = "base"; + + @Id + @Column(name = "PRODUCT_PRICE_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "PRODUCT_PRICE_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @OneToMany(fetch = FetchType.LAZY, mappedBy = "productPrice", cascade = CascadeType.ALL) + private Set descriptions = new HashSet(); + + @NotEmpty + @Pattern(regexp = "^[a-zA-Z0-9_]*$") + @Column(name = "PRODUCT_PRICE_CODE", nullable = false) + private String code = DEFAULT_PRICE_CODE; + + @Column(name = "PRODUCT_PRICE_AMOUNT", nullable = true) + private BigDecimal productPriceAmount = new BigDecimal(0); + + @Column(name = "PRODUCT_PRICE_TYPE", length = 20) + @Enumerated(value = EnumType.STRING) + private ProductPriceType productPriceType = ProductPriceType.ONE_TIME; + + @Column(name = "DEFAULT_PRICE") + private boolean defaultPrice = false; + + @Temporal(TemporalType.DATE) + @Column(name = "PRODUCT_PRICE_SPECIAL_ST_DATE") + private Date productPriceSpecialStartDate; + + @Temporal(TemporalType.DATE) + @Column(name = "PRODUCT_PRICE_SPECIAL_END_DATE") + private Date productPriceSpecialEndDate; + + @Column(name = "PRODUCT_PRICE_SPECIAL_AMOUNT") + private BigDecimal productPriceSpecialAmount; + + @JsonIgnore + @ManyToOne(targetEntity = ProductAvailability.class) + @JoinColumn(name = "PRODUCT_AVAIL_ID", nullable = false) + private ProductAvailability productAvailability; + + @Column(name = "PRODUCT_IDENTIFIER_ID", nullable = true) + private Long productIdentifierId; + + public ProductPrice() { + } + + @Override + public Long getId() { + return this.id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public BigDecimal getProductPriceAmount() { + return productPriceAmount; + } + + public void setProductPriceAmount(BigDecimal productPriceAmount) { + this.productPriceAmount = productPriceAmount; + } + + public Date getProductPriceSpecialStartDate() { + return CloneUtils.clone(productPriceSpecialStartDate); + } + + public void setProductPriceSpecialStartDate(Date productPriceSpecialStartDate) { + this.productPriceSpecialStartDate = CloneUtils.clone(productPriceSpecialStartDate); + } + + public Date getProductPriceSpecialEndDate() { + return CloneUtils.clone(productPriceSpecialEndDate); + } + + public void setProductPriceSpecialEndDate(Date productPriceSpecialEndDate) { + this.productPriceSpecialEndDate = CloneUtils.clone(productPriceSpecialEndDate); + } + + public BigDecimal getProductPriceSpecialAmount() { + return productPriceSpecialAmount; + } + + public void setProductPriceSpecialAmount(BigDecimal productPriceSpecialAmount) { + this.productPriceSpecialAmount = productPriceSpecialAmount; + } + + public Set getDescriptions() { + return descriptions; + } + + public void setDescriptions(Set descriptions) { + this.descriptions = descriptions; + } + + public boolean isDefaultPrice() { + return defaultPrice; + } + + public void setDefaultPrice(boolean defaultPrice) { + this.defaultPrice = defaultPrice; + } + + public void setProductAvailability(ProductAvailability productAvailability) { + this.productAvailability = productAvailability; + } + + public ProductAvailability getProductAvailability() { + return productAvailability; + } + + public void setCode(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + + public void setProductPriceType(ProductPriceType productPriceType) { + this.productPriceType = productPriceType; + } + + public ProductPriceType getProductPriceType() { + return productPriceType; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/price/ProductPriceDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/price/ProductPriceDescription.java new file mode 100755 index 0000000000..bdc007905d --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/price/ProductPriceDescription.java @@ -0,0 +1,64 @@ +package com.salesmanager.core.model.catalog.product.price; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.description.Description; + +@Entity +@Table(name="PRODUCT_PRICE_DESCRIPTION", +uniqueConstraints={ + @UniqueConstraint(columnNames={ + "PRODUCT_PRICE_ID", + "LANGUAGE_ID" + }) + } +) + +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "product_price_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +public class ProductPriceDescription extends Description {; + + /** + * + */ + private static final long serialVersionUID = 1L; + + public final static String DEFAULT_PRICE_DESCRIPTION = "DEFAULT"; + + @JsonIgnore + @ManyToOne(targetEntity = ProductPrice.class) + @JoinColumn(name = "PRODUCT_PRICE_ID", nullable = false) + private ProductPrice productPrice; + + + @Column(name = "PRICE_APPENDER") + private String priceAppender; + + public String getPriceAppender() { + return priceAppender; + } + + public void setPriceAppender(String priceAppender) { + this.priceAppender = priceAppender; + } + + public ProductPriceDescription() { + } + + public ProductPrice getProductPrice() { + return productPrice; + } + + public void setProductPrice(ProductPrice productPrice) { + this.productPrice = productPrice; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/price/ProductPriceType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/price/ProductPriceType.java new file mode 100755 index 0000000000..eed7b058d5 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/price/ProductPriceType.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.catalog.product.price; + +public enum ProductPriceType { + + ONE_TIME, MONTHLY + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/relationship/ProductRelationship.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/relationship/ProductRelationship.java new file mode 100755 index 0000000000..7a06a0d745 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/relationship/ProductRelationship.java @@ -0,0 +1,120 @@ +package com.salesmanager.core.model.catalog.product.relationship; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + +@Entity +@Table(name = "PRODUCT_RELATIONSHIP") +public class ProductRelationship extends SalesManagerEntity implements Serializable { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "PRODUCT_RELATIONSHIP_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "PRODUCT_RELATION_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @ManyToOne(targetEntity = MerchantStore.class) + @JoinColumn(name="MERCHANT_ID",nullable=false) + private MerchantStore store; + + @ManyToOne(targetEntity = Product.class) + @JoinColumn(name="PRODUCT_ID",updatable=false,nullable=true) + private Product product = null; + + @ManyToOne(targetEntity = Product.class) + @JoinColumn(name="RELATED_PRODUCT_ID",updatable=false,nullable=true) + private Product relatedProduct = null; + + @Column(name="CODE") + private String code; + + @Column(name="ACTIVE") + private boolean active = true; + + public Product getProduct() { + return product; + } + + + + public void setProduct(Product product) { + this.product = product; + } + + + + public Product getRelatedProduct() { + return relatedProduct; + } + + + + public void setRelatedProduct(Product relatedProduct) { + this.relatedProduct = relatedProduct; + } + + + + public String getCode() { + return code; + } + + + + public void setCode(String code) { + this.code = code; + } + + + + public boolean isActive() { + return active; + } + + + + public void setActive(boolean active) { + this.active = active; + } + + + + public ProductRelationship() { + } + + + + public MerchantStore getStore() { + return store; + } + + public void setStore(MerchantStore store) { + this.store = store; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/relationship/ProductRelationshipType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/relationship/ProductRelationshipType.java new file mode 100755 index 0000000000..cc49a24f25 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/relationship/ProductRelationshipType.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.catalog.product.relationship; + +public enum ProductRelationshipType { + + FEATURED_ITEM, RELATED_ITEM, BUNDLED_ITEM + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/review/ProductReview.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/review/ProductReview.java new file mode 100755 index 0000000000..0cbb6a9be1 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/review/ProductReview.java @@ -0,0 +1,159 @@ +package com.salesmanager.core.model.catalog.product.review; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.UniqueConstraint; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.generic.SalesManagerEntity; + +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "PRODUCT_REVIEW", uniqueConstraints={ + @UniqueConstraint(columnNames={ + "CUSTOMERS_ID", + "PRODUCT_ID" + }) + } +) +public class ProductReview extends SalesManagerEntity implements Auditable { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "PRODUCT_REVIEW_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", + pkColumnValue = "PRODUCT_REVIEW_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Embedded + private AuditSection audit = new AuditSection(); + + @Column(name = "REVIEWS_RATING") + private Double reviewRating; + + @Column(name = "REVIEWS_READ") + private Long reviewRead; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "REVIEW_DATE") + private Date reviewDate; + + @Column(name = "STATUS") + private Integer status; + + @JsonIgnore + @ManyToOne + @JoinColumn(name="CUSTOMERS_ID") + private Customer customer; + + @OneToOne + @JoinColumn(name="PRODUCT_ID") + private Product product; + + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "productReview") + private Set descriptions = new HashSet(); + + public ProductReview() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Double getReviewRating() { + return reviewRating; + } + + public void setReviewRating(Double reviewRating) { + this.reviewRating = reviewRating; + } + + public Long getReviewRead() { + return reviewRead; + } + + public void setReviewRead(Long reviewRead) { + this.reviewRead = reviewRead; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + } + + public Product getProduct() { + return product; + } + + public void setProduct(Product product) { + this.product = product; + } + + public Set getDescriptions() { + return descriptions; + } + + public void setDescriptions(Set descriptions) { + this.descriptions = descriptions; + } + + @Override + public AuditSection getAuditSection() { + return audit; + } + + @Override + public void setAuditSection(AuditSection audit) { + this.audit = audit; + } + + public Date getReviewDate() { + return reviewDate; + } + + public void setReviewDate(Date reviewDate) { + this.reviewDate = reviewDate; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/review/ProductReviewDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/review/ProductReviewDescription.java new file mode 100755 index 0000000000..eecf85717b --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/review/ProductReviewDescription.java @@ -0,0 +1,59 @@ +/* + * Licensed to csti consulting + * You may obtain a copy of the License at + * + * http://www.csticonsulting.com + * Copyright (c) 2006-Aug 24, 2010 Consultation CS-TI inc. + * + * 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 com.salesmanager.core.model.catalog.product.review; + +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.description.Description; +import com.salesmanager.core.model.reference.language.Language; + +@Entity +@Table(name = "PRODUCT_REVIEW_DESCRIPTION", uniqueConstraints={ + @UniqueConstraint(columnNames={ + "PRODUCT_REVIEW_ID", + "LANGUAGE_ID" + }) +}) + +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "product_review_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +public class ProductReviewDescription extends Description { + private static final long serialVersionUID = 1L; + + @ManyToOne(targetEntity = ProductReview.class) + @JoinColumn(name="PRODUCT_REVIEW_ID") + private ProductReview productReview; + + public ProductReviewDescription() { + } + + public ProductReviewDescription(Language language, String name) { + this.setLanguage(language); + this.setName(name); + } + + public ProductReview getProductReview() { + return productReview; + } + + public void setProductReview(ProductReview productReview) { + this.productReview = productReview; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/type/ProductType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/type/ProductType.java new file mode 100755 index 0000000000..702ce5a1ea --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/type/ProductType.java @@ -0,0 +1,132 @@ +package com.salesmanager.core.model.catalog.product.type; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "PRODUCT_TYPE") +public class ProductType extends SalesManagerEntity implements Auditable { + private static final long serialVersionUID = 1L; + + public final static String GENERAL_TYPE = "GENERAL"; + + @Id + @Column(name = "PRODUCT_TYPE_ID", unique = true, nullable = false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", + valueColumnName = "SEQ_COUNT", pkColumnValue = "PRD_TYPE_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "productType") + private Set descriptions = new HashSet(); + + @Column(name = "PRD_TYPE_CODE") + private String code; + + @Column(name = "PRD_TYPE_ADD_TO_CART") + private Boolean allowAddToCart; + + @Column(name = "PRD_TYPE_VISIBLE") + private Boolean visible; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "MERCHANT_ID", nullable = true) + private MerchantStore merchantStore; + + public ProductType() {} + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection auditSection) { + this.auditSection = auditSection; + } + + public boolean isAllowAddToCart() { + return allowAddToCart; + } + + public void setAllowAddToCart(boolean allowAddToCart) { + this.allowAddToCart = allowAddToCart; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public Boolean getAllowAddToCart() { + return allowAddToCart; + } + + public void setAllowAddToCart(Boolean allowAddToCart) { + this.allowAddToCart = allowAddToCart; + } + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + +public Set getDescriptions() { + return descriptions; +} + +public void setDescriptions(Set descriptions) { + this.descriptions = descriptions; +} + +public Boolean getVisible() { + return visible; +} + +public void setVisible(Boolean visible) { + this.visible = visible; +} + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/type/ProductTypeDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/type/ProductTypeDescription.java new file mode 100644 index 0000000000..43cfe92fc1 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/type/ProductTypeDescription.java @@ -0,0 +1,37 @@ +package com.salesmanager.core.model.catalog.product.type; + +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.description.Description; + +@Entity +@Table(name = "PRODUCT_TYPE_DESCRIPTION", + uniqueConstraints = {@UniqueConstraint(columnNames = {"PRODUCT_TYPE_ID", "LANGUAGE_ID"})}) + +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "product_type_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +public class ProductTypeDescription extends Description { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @ManyToOne(targetEntity = ProductType.class) + @JoinColumn(name = "PRODUCT_TYPE_ID", nullable = false) + private ProductType productType; + + public ProductType getProductType() { + return productType; + } + + public void setProductType(ProductType productType) { + this.productType = productType; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/variant/ProductVariant.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/variant/ProductVariant.java new file mode 100644 index 0000000000..4a8f032fe8 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/variant/ProductVariant.java @@ -0,0 +1,213 @@ +package com.salesmanager.core.model.catalog.product.variant; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.UniqueConstraint; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Pattern; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.variation.ProductVariation; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; + + +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "PRODUCT_VARIANT", +indexes = @Index(columnList = "PRODUCT_ID"), +uniqueConstraints = + @UniqueConstraint(columnNames = { + "PRODUCT_ID", + "SKU" })) +public class ProductVariant extends SalesManagerEntity implements Auditable { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "PRODUCT_VARIANT_ID", unique = true, nullable = false) + @TableGenerator(name = "TABLE_GEN", + table = "SM_SEQUENCER", + pkColumnName = "SEQ_NAME", + valueColumnName = "SEQ_COUNT", + pkColumnValue = "PRODUCT_VAR_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @Column(name = "DATE_AVAILABLE") + @Temporal(TemporalType.TIMESTAMP) + private Date dateAvailable = new Date(); + + @Column(name = "AVAILABLE") + private boolean available = true; + + @Column(name = "DEFAULT_SELECTION") + private boolean defaultSelection = true; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "PRODUCT_VARIATION_ID", nullable = true) + private ProductVariation variation; + + @ManyToOne(targetEntity = Product.class) + @JoinColumn(name = "PRODUCT_ID", nullable = false) + private Product product; + + @Column(name = "CODE", nullable = true) + private String code; + + @Column(name="SORT_ORDER") + private Integer sortOrder = 0; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "PRODUCT_VARIATION_VALUE_ID", nullable = true) + private ProductVariation variationValue; + + @NotEmpty + @Pattern(regexp="^[a-zA-Z0-9_]*$") + @Column(name = "SKU") + private String sku; + + @ManyToOne(targetEntity = ProductVariantGroup.class) + @JoinColumn(name = "PRODUCT_VARIANT_GROUP_ID", nullable = true) + private ProductVariantGroup productVariantGroup; + + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="productVariant") + private Set availabilities = new HashSet(); + + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection audit) { + this.auditSection = audit; + + } + + @Override + public Long getId() { + return this.id; + } + + @Override + public void setId(Long id) { + this.id = id; + + } + + public Date getDateAvailable() { + return dateAvailable; + } + + public void setDateAvailable(Date dateAvailable) { + this.dateAvailable = dateAvailable; + } + + public boolean isAvailable() { + return available; + } + + public void setAvailable(boolean available) { + this.available = available; + } + + public ProductVariation getVariation() { + return variation; + } + + public void setVariation(ProductVariation variation) { + this.variation = variation; + } + + public Product getProduct() { + return product; + } + + public void setProduct(Product product) { + this.product = product; + } + + public ProductVariation getVariationValue() { + return variationValue; + } + + public void setVariationValue(ProductVariation variationValue) { + this.variationValue = variationValue; + } + + public boolean isDefaultSelection() { + return defaultSelection; + } + + public void setDefaultSelection(boolean defaultSelection) { + this.defaultSelection = defaultSelection; + } + + public String getSku() { + return sku; + } + + public void setSku(String sku) { + this.sku = sku; + } + + public Integer getSortOrder() { + return sortOrder; + } + + public void setSortOrder(Integer sortOrder) { + this.sortOrder = sortOrder; + } + + + public String getCode() { return code; } + + public void setCode(String code) { this.code = code; } + + public ProductVariantGroup getProductVariantGroup() { + return productVariantGroup; + } + + public void setProductVariantGroup(ProductVariantGroup productVariantGroup) { + this.productVariantGroup = productVariantGroup; + } + + public Set getAvailabilities() { + return availabilities; + } + + public void setAvailabilities(Set availabilities) { + this.availabilities = availabilities; + } + + + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/variant/ProductVariantGroup.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/variant/ProductVariantGroup.java new file mode 100644 index 0000000000..cc46644385 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/variant/ProductVariantGroup.java @@ -0,0 +1,96 @@ +package com.salesmanager.core.model.catalog.product.variant; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + +/** + * Extra properties on a group of variants + * @author carlsamson + * + */ +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name="PRODUCT_VARIANT_GROUP") +public class ProductVariantGroup extends SalesManagerEntity { + + private static final long serialVersionUID = 1L; + + + @Id + @Column(name = "PRODUCT_VARIANT_GROUP_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", + table = "SM_SEQUENCER", + pkColumnName = "SEQ_NAME", + valueColumnName = "SEQ_COUNT", pkColumnValue = "PRODUCT_VAR_GROUP_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="productVariantGroup") + private List images = new ArrayList(); + + @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.DETACH }, mappedBy = "productVariantGroup") + private Set productVariants = new HashSet(); + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore merchantStore; + + @Override + public Long getId() { + return this.id; + } + + @Override + public void setId(Long id) { + this.id=id; + + } + + public List getImages() { + return images; + } + + public void setImages(List images) { + this.images = images; + } + + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public Set getProductVariants() { + return productVariants; + } + + public void setProductVariants(Set productVariants) { + this.productVariants = productVariants; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/variant/ProductVariantImage.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/variant/ProductVariantImage.java new file mode 100755 index 0000000000..a767c88bde --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/variant/ProductVariantImage.java @@ -0,0 +1,97 @@ +package com.salesmanager.core.model.catalog.product.variant; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import com.salesmanager.core.model.generic.SalesManagerEntity; + +@Entity +@Table(name = "PRODUCT_VAR_IMAGE") +public class ProductVariantImage extends SalesManagerEntity { + + + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "PRODUCT_VAR_IMAGE_ID") + @TableGenerator(name = "TABLE_GEN", + table = "SM_SEQUENCER", + pkColumnName = "SEQ_NAME", + valueColumnName = "SEQ_COUNT", + pkColumnValue = "PRD_VAR_IMG_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Column(name = "PRODUCT_IMAGE") + private String productImage; + + @Column(name = "DEFAULT_IMAGE") + private boolean defaultImage = true; + + @ManyToOne(targetEntity = ProductVariantGroup.class) + @JoinColumn(name = "PRODUCT_VARIANT_GROUP_ID", nullable = false) + private ProductVariantGroup productVariantGroup; + + @OneToMany(fetch = FetchType.LAZY, mappedBy = "productVariantImage", cascade = CascadeType.ALL) + private Set descriptions = new HashSet(); + + public ProductVariantImage(){ + } + + public String getProductImage() { + return productImage; + } + + public void setProductImage(String productImage) { + this.productImage = productImage; + } + + public boolean isDefaultImage() { + return defaultImage; + } + + public void setDefaultImage(boolean defaultImage) { + this.defaultImage = defaultImage; + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public Set getDescriptions() { + return descriptions; + } + + public void setDescriptions(Set descriptions) { + this.descriptions = descriptions; + } + + public ProductVariantGroup getProductVariantGroup() { + return productVariantGroup; + } + + public void setProductVariantGroup(ProductVariantGroup productVariantGroup) { + this.productVariantGroup = productVariantGroup; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/variant/ProductVariantImageDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/variant/ProductVariantImageDescription.java new file mode 100755 index 0000000000..daf704af59 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/variant/ProductVariantImageDescription.java @@ -0,0 +1,59 @@ +package com.salesmanager.core.model.catalog.product.variant; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.common.description.Description; + +@Entity +@Table(name="PRODUCT_VAR_IMAGE_DESCRIPTION", uniqueConstraints={ + @UniqueConstraint(columnNames={ + "PRODUCT_VAR_IMAGE_ID", + "LANGUAGE_ID" + }) + } +) +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "product_var_image_desc_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +public class ProductVariantImageDescription extends Description { + private static final long serialVersionUID = 1L; + + @ManyToOne(targetEntity = ProductVariantImage.class) + @JoinColumn(name = "PRODUCT_VAR_IMAGE_ID", nullable = false) + private ProductVariantImage productVariantImage; + + @JsonIgnore + @ManyToOne(targetEntity = Product.class) + @JoinColumn(name = "PRODUCT_ID", nullable = false) + private Product product; + + + @Column(name="ALT_TAG", length=100) + private String altTag; + + + public String getAltTag() { + return altTag; + } + + public void setAltTag(String altTag) { + this.altTag = altTag; + } + + public ProductVariantImage getProductVariantImage() { + return productVariantImage; + } + + public void setProductVariantImage(ProductVariantImage productVariantImage) { + this.productVariantImage = productVariantImage; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/variation/ProductVariation.java b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/variation/ProductVariation.java new file mode 100644 index 0000000000..197f92e453 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/catalog/product/variation/ProductVariation.java @@ -0,0 +1,150 @@ +package com.salesmanager.core.model.catalog.product.variation; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; +import javax.validation.constraints.NotEmpty; + +import com.salesmanager.core.model.catalog.product.attribute.Optionable; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + + +/** + * Product configuration pre 3.0 + * Contains possible product variations + * + * color - red + * size - small + * @author carlsamson + * + */ +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "PRODUCT_VARIATION", uniqueConstraints= +@UniqueConstraint(columnNames = {"MERCHANT_ID", "PRODUCT_OPTION_ID", "OPTION_VALUE_ID"})) +public class ProductVariation extends SalesManagerEntity implements Optionable, Auditable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @Id + @Column(name = "PRODUCT_VARIATION_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "PRODUCT_VARIN_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + /** can exist detached **/ + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore merchantStore; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="PRODUCT_OPTION_ID", nullable=false) + private ProductOption productOption; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="OPTION_VALUE_ID", nullable=false) + private ProductOptionValue productOptionValue; + + @NotEmpty + @Column(name="CODE", length=100, nullable=false) + private String code; + + @Column(name="SORT_ORDER") + private Integer sortOrder; + + @Column(name="VARIANT_DEFAULT") + private boolean variantDefault=false; + + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection audit) { + this.auditSection = audit; + + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + + } + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public ProductOption getProductOption() { + return productOption; + } + + public void setProductOption(ProductOption productOption) { + this.productOption = productOption; + } + + public ProductOptionValue getProductOptionValue() { + return productOptionValue; + } + + public void setProductOptionValue(ProductOptionValue productOptionValue) { + this.productOptionValue = productOptionValue; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public Integer getSortOrder() { + return sortOrder; + } + + public void setSortOrder(Integer sortOrder) { + this.sortOrder = sortOrder; + } + + public boolean isVariantDefault() { + return variantDefault; + } + + public void setVariantDefault(boolean variantDefault) { + this.variantDefault = variantDefault; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/common/Address.java b/sm-core-model/src/main/java/com/salesmanager/core/model/common/Address.java new file mode 100755 index 0000000000..a1b44ff299 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/common/Address.java @@ -0,0 +1,62 @@ +package com.salesmanager.core.model.common; + +import java.io.Serializable; + + +public class Address implements Serializable { + + + /** + * + */ + private static final long serialVersionUID = 1L; + private String city; + private String postalCode; + private String stateProvince; + private String zone;//code + private String country;//code + + public void setStateProvince(String stateProvince) { + this.stateProvince = stateProvince; + } + + public void setCountry(String country) { + this.country = country; + } + + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public String getStateProvince() { + return stateProvince; + } + + public String getCountry() { + return country; + } + + public void setZone(String zone) { + this.zone = zone; + } + + public String getZone() { + return zone; + } + + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/common/Billing.java b/sm-core-model/src/main/java/com/salesmanager/core/model/common/Billing.java new file mode 100755 index 0000000000..d4e47de8a5 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/common/Billing.java @@ -0,0 +1,161 @@ +package com.salesmanager.core.model.common; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +import javax.validation.constraints.NotEmpty; + +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.zone.Zone; + +@Embeddable +public class Billing { + + @NotEmpty + @Column (name ="BILLING_LAST_NAME", length=64, nullable=false) + private String lastName; + + @NotEmpty + @Column (name ="BILLING_FIRST_NAME", length=64, nullable=false) + private String firstName; + + + + @Column (name ="BILLING_COMPANY", length=100) + private String company; + + @Column (name ="BILLING_STREET_ADDRESS", length=256) + private String address; + + + @Column (name ="BILLING_CITY", length=100) + private String city; + + @Column (name ="BILLING_POSTCODE", length=20) + private String postalCode; + + @Column(name="BILLING_TELEPHONE", length=32) + private String telephone; + + @Column (name ="BILLING_STATE", length=100) + private String state; + + @Column (name ="LONGITUDE", length=100) + private String longitude; + + @Column (name ="LATITUDE", length=100) + private String latitude; + + + @ManyToOne(fetch = FetchType.LAZY, targetEntity = Country.class) + @JoinColumn(name="BILLING_COUNTRY_ID", nullable=false) + private Country country; + + + @ManyToOne(fetch = FetchType.LAZY, targetEntity = Zone.class) + @JoinColumn(name="BILLING_ZONE_ID", nullable=true) + private Zone zone; + + + + public String getCompany() { + return company; + } + + public void setCompany(String company) { + this.company = company; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public Country getCountry() { + return country; + } + + public void setCountry(Country country) { + this.country = country; + } + + public Zone getZone() { + return zone; + } + + public void setZone(Zone zone) { + this.zone = zone; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public void setTelephone(String telephone) { + this.telephone = telephone; + } + + public String getTelephone() { + return telephone; + } + + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } + + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/common/CredentialsReset.java b/sm-core-model/src/main/java/com/salesmanager/core/model/common/CredentialsReset.java new file mode 100644 index 0000000000..eb93eed1ce --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/common/CredentialsReset.java @@ -0,0 +1,36 @@ +package com.salesmanager.core.model.common; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +@Embeddable +public class CredentialsReset { + + @Column (name ="RESET_CREDENTIALS_REQ", length=256) + private String credentialsRequest; + + @Temporal(TemporalType.DATE) + @Column(name = "RESET_CREDENTIALS_EXP") + private Date credentialsRequestExpiry = new Date(); + + public String getCredentialsRequest() { + return credentialsRequest; + } + + public void setCredentialsRequest(String credentialsRequest) { + this.credentialsRequest = credentialsRequest; + } + + public Date getCredentialsRequestExpiry() { + return credentialsRequestExpiry; + } + + public void setCredentialsRequestExpiry(Date credentialsRequestExpiry) { + this.credentialsRequestExpiry = credentialsRequestExpiry; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/common/Criteria.java b/sm-core-model/src/main/java/com/salesmanager/core/model/common/Criteria.java new file mode 100755 index 0000000000..77d7dbd5e1 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/common/Criteria.java @@ -0,0 +1,140 @@ +package com.salesmanager.core.model.common; + +import java.util.List; + +import com.salesmanager.core.model.merchant.MerchantStore; + +public class Criteria { + + // legacy pagination + private int startIndex = 0; + private int maxCount = 0; + // new pagination + private int startPage = 0; + private int pageSize = 10; + private boolean legacyPagination = true; + private String code; + private String name; + private String language; + private String user; + private String storeCode; + private List storeIds; + + private CriteriaOrderBy orderBy = CriteriaOrderBy.DESC; + private String criteriaOrderByField; + private String search; + + public int getMaxCount() { + return maxCount; + } + + public void setMaxCount(int maxCount) { + this.maxCount = maxCount; + } + + public int getStartIndex() { + return startIndex; + } + + public void setStartIndex(int startIndex) { + this.startIndex = startIndex; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public void setOrderBy(CriteriaOrderBy orderBy) { + this.orderBy = orderBy; + } + + public CriteriaOrderBy getOrderBy() { + return orderBy; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCriteriaOrderByField() { + return criteriaOrderByField; + } + + public void setCriteriaOrderByField(String criteriaOrderByField) { + this.criteriaOrderByField = criteriaOrderByField; + } + + public String getSearch() { + return search; + } + + public void setSearch(String search) { + this.search = search; + } + + public String getStoreCode() { + return storeCode; + } + + public void setStoreCode(String storeCode) { + this.storeCode = storeCode; + } + + public int getPageSize() { + return pageSize; + } + + public void setPageSize(int pageSize) { + this.pageSize = pageSize; + } + + public int getStartPage() { + return startPage; + } + + public void setStartPage(int startPage) { + this.startPage = startPage; + } + + public boolean isLegacyPagination() { + return legacyPagination; + } + + public void setLegacyPagination(boolean legacyPagination) { + this.legacyPagination = legacyPagination; + } + + public List getStoreIds() { + return storeIds; + } + + public void setStoreIds(List storeIds) { + this.storeIds = storeIds; + } + + +} \ No newline at end of file diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/common/CriteriaOrderBy.java b/sm-core-model/src/main/java/com/salesmanager/core/model/common/CriteriaOrderBy.java new file mode 100755 index 0000000000..c9e0c5f467 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/common/CriteriaOrderBy.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.common; + +public enum CriteriaOrderBy { + + + ASC, DESC +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/common/Delivery.java b/sm-core-model/src/main/java/com/salesmanager/core/model/common/Delivery.java new file mode 100755 index 0000000000..3272763690 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/common/Delivery.java @@ -0,0 +1,152 @@ +package com.salesmanager.core.model.common; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Transient; + +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.zone.Zone; + +@Embeddable +public class Delivery { + + @Column (name ="DELIVERY_LAST_NAME", length=64) + private String lastName; + + @Column (name ="DELIVERY_FIRST_NAME", length=64) + private String firstName; + + @Column (name ="DELIVERY_COMPANY", length=100) + private String company; + + @Column (name ="DELIVERY_STREET_ADDRESS", length=256) + private String address; + + @Column (name ="DELIVERY_CITY", length=100) + private String city; + + @Column (name ="DELIVERY_POSTCODE", length=20) + private String postalCode; + + @Column (name ="DELIVERY_STATE", length=100) + private String state; + + @Column(name="DELIVERY_TELEPHONE", length=32) + private String telephone; + + @ManyToOne(fetch = FetchType.LAZY, targetEntity = Country.class) + @JoinColumn(name="DELIVERY_COUNTRY_ID", nullable=true) + private Country country; + + + @ManyToOne(fetch = FetchType.LAZY, targetEntity = Zone.class) + @JoinColumn(name="DELIVERY_ZONE_ID", nullable=true) + private Zone zone; + + @Transient + private String latitude = null; + + @Transient + private String longitude = null; + + + public String getCompany() { + return company; + } + + public void setCompany(String company) { + this.company = company; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public Country getCountry() { + return country; + } + + public void setCountry(Country country) { + this.country = country; + } + + public Zone getZone() { + return zone; + } + + public void setZone(Zone zone) { + this.zone = zone; + } + + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public void setTelephone(String telephone) { + this.telephone = telephone; + } + + public String getTelephone() { + return telephone; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/common/EntityList.java b/sm-core-model/src/main/java/com/salesmanager/core/model/common/EntityList.java new file mode 100755 index 0000000000..119df97094 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/common/EntityList.java @@ -0,0 +1,35 @@ +package com.salesmanager.core.model.common; + +import java.io.Serializable; + +public class EntityList implements Serializable { + + + /** + * + */ + private static final long serialVersionUID = 1L; + //private int totalCount; + private long totalCount; + private int totalPages; + +/* public int getTotalCount() { + return totalCount; + }*/ +/* public void setTotalCount(int totalCount) { + this.totalCount = totalCount; + }*/ + public int getTotalPages() { + return totalPages == 0 ? totalPages+1:totalPages; + } + public void setTotalPages(int totalPage) { + this.totalPages = totalPage; + } + public long getTotalCount() { + return totalCount; + } + public void setTotalCount(long totalCount) { + this.totalCount = totalCount; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/common/GenericEntityList.java b/sm-core-model/src/main/java/com/salesmanager/core/model/common/GenericEntityList.java new file mode 100755 index 0000000000..0365d48c3d --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/common/GenericEntityList.java @@ -0,0 +1,22 @@ +package com.salesmanager.core.model.common; + +import java.util.List; + +public class GenericEntityList extends EntityList { + + /** + * + */ + private static final long serialVersionUID = 1L; + + List list; + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/common/UserContext.java b/sm-core-model/src/main/java/com/salesmanager/core/model/common/UserContext.java new file mode 100644 index 0000000000..4ceb8ed411 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/common/UserContext.java @@ -0,0 +1,35 @@ +package com.salesmanager.core.model.common; + +public final class UserContext implements AutoCloseable { + + private String ipAddress; + + private static ThreadLocal instance = new ThreadLocal<>(); + + private UserContext() {} + + public static UserContext create() { + UserContext context = new UserContext(); + instance.set(context); + return context; + } + + + @Override + public void close() throws Exception { + instance.remove(); + } + + public static UserContext getCurrentInstance() { + return instance.get(); + } + + public String getIpAddress() { + return ipAddress; + } + + public void setIpAddress(String ipAddress) { + this.ipAddress = ipAddress; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/common/audit/AuditListener.java b/sm-core-model/src/main/java/com/salesmanager/core/model/common/audit/AuditListener.java new file mode 100755 index 0000000000..af7bc639cb --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/common/audit/AuditListener.java @@ -0,0 +1,36 @@ +package com.salesmanager.core.model.common.audit; + +import java.util.Date; +import javax.persistence.PrePersist; +import javax.persistence.PreUpdate; + +public class AuditListener { + + @PrePersist + public void onSave(Object o) { + if (o instanceof Auditable) { + Auditable audit = (Auditable) o; + AuditSection auditSection = audit.getAuditSection(); + + auditSection.setDateModified(new Date()); + if (auditSection.getDateCreated() == null) { + auditSection.setDateCreated(new Date()); + } + audit.setAuditSection(auditSection); + } + } + + @PreUpdate + public void onUpdate(Object o) { + if (o instanceof Auditable) { + Auditable audit = (Auditable) o; + AuditSection auditSection = audit.getAuditSection(); + + auditSection.setDateModified(new Date()); + if (auditSection.getDateCreated() == null) { + auditSection.setDateCreated(new Date()); + } + audit.setAuditSection(auditSection); + } + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/common/audit/AuditSection.java b/sm-core-model/src/main/java/com/salesmanager/core/model/common/audit/AuditSection.java new file mode 100755 index 0000000000..92608c0a9f --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/common/audit/AuditSection.java @@ -0,0 +1,62 @@ +package com.salesmanager.core.model.common.audit; + +import java.io.Serializable; +import java.util.Date; +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.apache.commons.lang3.StringUtils; + +import com.salesmanager.core.utils.CloneUtils; + + +@Embeddable +public class AuditSection implements Serializable { + + + private static final long serialVersionUID = 1L; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "DATE_CREATED") + private Date dateCreated; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "DATE_MODIFIED") + private Date dateModified; + + @Column(name = "UPDT_ID", length = 60) + private String modifiedBy; + + public AuditSection() {} + + public Date getDateCreated() { + return CloneUtils.clone(dateCreated); + } + + public void setDateCreated(Date dateCreated) { + this.dateCreated = CloneUtils.clone(dateCreated); + } + + public Date getDateModified() { + return CloneUtils.clone(dateModified); + } + + public void setDateModified(Date dateModified) { + this.dateModified = CloneUtils.clone(dateModified); + } + + public String getModifiedBy() { + return modifiedBy; + } + + public void setModifiedBy(String modifiedBy) { + if(!StringUtils.isBlank(modifiedBy)) {//TODO + if(modifiedBy.length()>20) { + modifiedBy = modifiedBy.substring(0, 20); + } + } + this.modifiedBy = modifiedBy; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/common/audit/Auditable.java b/sm-core-model/src/main/java/com/salesmanager/core/model/common/audit/Auditable.java new file mode 100755 index 0000000000..e871f82c0b --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/common/audit/Auditable.java @@ -0,0 +1,8 @@ +package com.salesmanager.core.model.common.audit; + +public interface Auditable { + + AuditSection getAuditSection(); + + void setAuditSection(AuditSection audit); +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/common/description/Description.java b/sm-core-model/src/main/java/com/salesmanager/core/model/common/description/Description.java new file mode 100755 index 0000000000..99c1409c81 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/common/description/Description.java @@ -0,0 +1,113 @@ +package com.salesmanager.core.model.common.description; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.EntityListeners; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.MappedSuperclass; +import javax.validation.constraints.NotEmpty; + +import org.hibernate.annotations.Type; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.reference.language.Language; + +@MappedSuperclass +@EntityListeners(value = AuditListener.class) +@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +public class Description implements Auditable, Serializable { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "DESCRIPTION_ID") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "description_gen") + private Long id; + + @JsonIgnore + @Embedded + private AuditSection auditSection = new AuditSection(); + + @ManyToOne(optional = false) + @JoinColumn(name = "LANGUAGE_ID") + private Language language; + + @NotEmpty + @Column(name="NAME", nullable = false, length=120) + private String name; + + @Column(name="TITLE", length=100) + private String title; + + @Column(name="DESCRIPTION") + @Type(type = "org.hibernate.type.TextType") + private String description; + + public Description() { + } + + public Description(Language language, String name) { + this.setLanguage(language); + this.setName(name); + } + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection auditSection) { + this.auditSection = auditSection; + } + + public Language getLanguage() { + return language; + } + + public void setLanguage(Language language) { + this.language = language; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/content/Content.java b/sm-core-model/src/main/java/com/salesmanager/core/model/content/Content.java new file mode 100755 index 0000000000..b7b9a8ed74 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/content/Content.java @@ -0,0 +1,196 @@ +package com.salesmanager.core.model.content; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; +import javax.validation.Valid; + +import javax.validation.constraints.NotEmpty; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + + +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "CONTENT", +indexes = { @Index(name="CODE_IDX", columnList = "CODE")}, + uniqueConstraints = @UniqueConstraint(columnNames = {"MERCHANT_ID", "CODE"}) ) +public class Content extends SalesManagerEntity implements Serializable { + + + + private static final long serialVersionUID = 1772757159185494620L; + + @Id + @Column(name = "CONTENT_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "CONTENT_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @Valid + @OneToMany(mappedBy="content", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private List descriptions = new ArrayList(); + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore merchantStore; + + @NotEmpty + @Column(name="CODE", length=100, nullable=false) + private String code; + + @Column(name = "VISIBLE") + private boolean visible; + + @Column(name = "LINK_TO_MENU") + private boolean linkToMenu; + + @Column(name = "CONTENT_POSITION", length=10, nullable=true) + @Enumerated(value = EnumType.STRING) + private ContentPosition contentPosition; + + //Used for grouping + //BOX, SECTION, PAGE + @Column(name = "CONTENT_TYPE", length=10, nullable=true) + @Enumerated(value = EnumType.STRING) + private ContentType contentType; + + @Column(name = "SORT_ORDER") + private Integer sortOrder = 0; + + //A page can contain one product listing + @Column(name = "PRODUCT_GROUP", nullable = true) + private String productGroup; + + public String getProductGroup() { + return productGroup; + } + + public void setProductGroup(String productGroup) { + this.productGroup = productGroup; + } + + @Override + public Long getId() { + return this.id; + } + + @Override + public void setId(Long id) { + this.id = id; + + } + + public void setAuditSection(AuditSection auditSection) { + this.auditSection = auditSection; + } + + public AuditSection getAuditSection() { + return auditSection; + } + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public boolean isVisible() { + return visible; + } + + public void setVisible(boolean visible) { + this.visible = visible; + } + + + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + + public void setContentType(ContentType contentType) { + this.contentType = contentType; + } + + public ContentType getContentType() { + return contentType; + } + + public ContentDescription getDescription() { + + if(this.getDescriptions()!=null && this.getDescriptions().size()>0) { + return this.getDescriptions().get(0); + } + + return null; + + } + + public void setSortOrder(Integer sortOrder) { + this.sortOrder = sortOrder; + } + + public Integer getSortOrder() { + return sortOrder; + } + + public void setContentPosition(ContentPosition contentPosition) { + this.contentPosition = contentPosition; + } + + public ContentPosition getContentPosition() { + return contentPosition; + } + + + + public boolean isLinkToMenu() { + return linkToMenu; + } + + public void setLinkToMenu(boolean linkToMenu) { + this.linkToMenu = linkToMenu; + } + +} \ No newline at end of file diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/content/ContentDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/content/ContentDescription.java new file mode 100755 index 0000000000..223ec7693f --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/content/ContentDescription.java @@ -0,0 +1,104 @@ +package com.salesmanager.core.model.content; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.description.Description; +import com.salesmanager.core.model.reference.language.Language; + +@Entity +@Table(name="CONTENT_DESCRIPTION",uniqueConstraints={ + @UniqueConstraint(columnNames={ + "CONTENT_ID", + "LANGUAGE_ID" + }) + } +) + +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "content_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +//@SequenceGenerator(name = "description_gen", sequenceName = "content_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_SEQUENCE_START) +public class ContentDescription extends Description implements Serializable { + + + /** + * + */ + private static final long serialVersionUID = 1L; + + @ManyToOne(targetEntity = Content.class) + @JoinColumn(name = "CONTENT_ID", nullable = false) + private Content content; + + @Column(name="SEF_URL", length=120) + private String seUrl; + + + @Column(name="META_KEYWORDS") + private String metatagKeywords; + + @Column(name="META_TITLE") + private String metatagTitle; + + public String getMetatagTitle() { + return metatagTitle; + } + + public void setMetatagTitle(String metatagTitle) { + this.metatagTitle = metatagTitle; + } + + @Column(name="META_DESCRIPTION") + private String metatagDescription; + + public ContentDescription() { + } + + public ContentDescription(String name, Language language) { + this.setName(name); + this.setLanguage(language); + super.setId(0L); + } + + public Content getContent() { + return content; + } + + public void setContent(Content content) { + this.content = content; + } + + public String getSeUrl() { + return seUrl; + } + + public void setSeUrl(String seUrl) { + this.seUrl = seUrl; + } + + + public String getMetatagKeywords() { + return metatagKeywords; + } + + public void setMetatagKeywords(String metatagKeywords) { + this.metatagKeywords = metatagKeywords; + } + + public String getMetatagDescription() { + return metatagDescription; + } + + public void setMetatagDescription(String metatagDescription) { + this.metatagDescription = metatagDescription; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/content/ContentFile.java b/sm-core-model/src/main/java/com/salesmanager/core/model/content/ContentFile.java new file mode 100755 index 0000000000..6d3eea7055 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/content/ContentFile.java @@ -0,0 +1,22 @@ +package com.salesmanager.core.model.content; + +public abstract class ContentFile { + + + private String fileName; + private String mimeType; + public void setMimeType(String mimeType) { + this.mimeType = mimeType; + } + public String getMimeType() { + return mimeType; + } + public void setFileName(String fileName) { + this.fileName = fileName; + } + public String getFileName() { + return fileName; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/content/ContentPosition.java b/sm-core-model/src/main/java/com/salesmanager/core/model/content/ContentPosition.java new file mode 100755 index 0000000000..d9635a6ab9 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/content/ContentPosition.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.content; + +public enum ContentPosition { + + LEFT, RIGHT + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/content/ContentType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/content/ContentType.java new file mode 100755 index 0000000000..264b794c0c --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/content/ContentType.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.content; + +public enum ContentType { + + BOX, PAGE, SECTION + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/content/FileContentType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/content/FileContentType.java new file mode 100755 index 0000000000..aac28cc566 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/content/FileContentType.java @@ -0,0 +1,25 @@ +/** + * + */ +package com.salesmanager.core.model.content; + +/** + * Enum defining type of static content. + * Currently following type of static content can be store and managed within + * Shopizer CMS system + *
+ * 1. Static content like JS, CSS file etc
+ * 2. Digital Data (audio,video)
+ * 
+ * + * StaticContentType will be used to distinguish between Digital data and other type of static data + * stored with in the system. + * + * @author Umesh Awasthi + * @since 1.2 + * + */ +public enum FileContentType +{ + STATIC_FILE, IMAGE, LOGO, PRODUCT, PRODUCTLG, PROPERTY, VARIANT, MANUFACTURER, PRODUCT_DIGITAL, API_IMAGE, API_FILE +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/content/ImageContentFile.java b/sm-core-model/src/main/java/com/salesmanager/core/model/content/ImageContentFile.java new file mode 100755 index 0000000000..2a60e9a880 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/content/ImageContentFile.java @@ -0,0 +1,14 @@ +package com.salesmanager.core.model.content; + +import java.io.Serializable; + +public class ImageContentFile extends InputContentFile implements Serializable { + + + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/content/InputContentFile.java b/sm-core-model/src/main/java/com/salesmanager/core/model/content/InputContentFile.java new file mode 100755 index 0000000000..aeb318ff64 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/content/InputContentFile.java @@ -0,0 +1,33 @@ +package com.salesmanager.core.model.content; + +import java.io.InputStream; +import java.io.Serializable; + + +public class InputContentFile extends StaticContentFile implements Serializable +{ + + private static final long serialVersionUID = 1L; + + private InputStream file; + private String path; + + + public InputStream getFile() + { + return file; + } + public void setFile( InputStream file ) + { + this.file = file; + } + public String getPath() { + return path; + } + public void setPath(String path) { + this.path = path; + } + + + +} \ No newline at end of file diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/content/OutputContentFile.java b/sm-core-model/src/main/java/com/salesmanager/core/model/content/OutputContentFile.java new file mode 100755 index 0000000000..ef0600cd9d --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/content/OutputContentFile.java @@ -0,0 +1,26 @@ +package com.salesmanager.core.model.content; + +import java.io.ByteArrayOutputStream; +import java.io.Serializable; + +/** + * Data class responsible for carrying out static content data from Infispan cache to + * service layer. + * + * @author Umesh Awasthi + * @since 1.2 + */ +public class OutputContentFile extends StaticContentFile implements Serializable +{ + private static final long serialVersionUID = 1L; + private ByteArrayOutputStream file; + public ByteArrayOutputStream getFile() + { + return file; + } + public void setFile( ByteArrayOutputStream file ) + { + this.file = file; + } + +} \ No newline at end of file diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/content/StaticContentFile.java b/sm-core-model/src/main/java/com/salesmanager/core/model/content/StaticContentFile.java new file mode 100755 index 0000000000..0d2cbca24e --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/content/StaticContentFile.java @@ -0,0 +1,18 @@ +package com.salesmanager.core.model.content; + +public abstract class StaticContentFile extends ContentFile { + + private FileContentType fileContentType; + + public FileContentType getFileContentType() { + return fileContentType; + } + + public void setFileContentType(FileContentType fileContentType) { + this.fileContentType = fileContentType; + } + + + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/Customer.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/Customer.java new file mode 100755 index 0000000000..8008a77f74 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/Customer.java @@ -0,0 +1,358 @@ +package com.salesmanager.core.model.customer; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; +import javax.validation.Valid; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotEmpty; + +import org.hibernate.annotations.Cascade; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.catalog.product.review.ProductReview; +import com.salesmanager.core.model.common.Billing; +import com.salesmanager.core.model.common.CredentialsReset; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.customer.attribute.CustomerAttribute; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.utils.CloneUtils; + +@Entity +@Table(name = "CUSTOMER", + uniqueConstraints= + @UniqueConstraint(columnNames = {"MERCHANT_ID", "CUSTOMER_NICK"})) +public class Customer extends SalesManagerEntity implements Auditable { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "CUSTOMER_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", + pkColumnValue = "CUSTOMER_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @JsonIgnore + @Embedded + private AuditSection auditSection = new AuditSection(); + + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "customer") + private Set attributes = new HashSet(); + + @Column(name="CUSTOMER_GENDER", length=1, nullable=true) + @Enumerated(value = EnumType.STRING) + private CustomerGender gender; + + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="CUSTOMER_DOB") + private Date dateOfBirth; + + @Email + @NotEmpty + @Column(name="CUSTOMER_EMAIL_ADDRESS", length=96, nullable=false) + private String emailAddress; + + @Column(name="CUSTOMER_NICK", length=96) + private String nick;// unique username per store + + @Column(name="CUSTOMER_COMPANY", length=100) + private String company; + + @JsonIgnore + @Column(name="CUSTOMER_PASSWORD", length=60) + private String password; + + @Column(name="CUSTOMER_ANONYMOUS") + private boolean anonymous; + + @Column(name = "REVIEW_AVG") + private BigDecimal customerReviewAvg; + + @Column(name = "REVIEW_COUNT") + private Integer customerReviewCount; + + @Column(name="PROVIDER") + private String provider; + + + @ManyToOne(fetch = FetchType.LAZY, targetEntity = Language.class) + @JoinColumn(name = "LANGUAGE_ID", nullable=false) + private Language defaultLanguage; + + + @OneToMany(mappedBy = "customer", targetEntity = ProductReview.class) + private List reviews = new ArrayList(); + + @JsonIgnore + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore merchantStore; + + + @Embedded + private Delivery delivery = null; + + @Valid + @Embedded + private Billing billing = null; + + @JsonIgnore + @ManyToMany(fetch=FetchType.LAZY, cascade = {CascadeType.REFRESH}) + @JoinTable(name = "CUSTOMER_GROUP", joinColumns = { + @JoinColumn(name = "CUSTOMER_ID", nullable = false, updatable = false) } + , + inverseJoinColumns = { @JoinColumn(name = "GROUP_ID", + nullable = false, updatable = false) } + ) + @Cascade({ + org.hibernate.annotations.CascadeType.DETACH, + org.hibernate.annotations.CascadeType.LOCK, + org.hibernate.annotations.CascadeType.REFRESH, + org.hibernate.annotations.CascadeType.REPLICATE + + }) + private List groups = new ArrayList(); + + @JsonIgnore + @Transient + private String showCustomerStateList; + + @JsonIgnore + @Transient + private String showBillingStateList; + + @JsonIgnore + @Transient + private String showDeliveryStateList; + + @Embedded + private CredentialsReset credentialsResetRequest = null; + + public Customer() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + + + public Date getDateOfBirth() { + return CloneUtils.clone(dateOfBirth); + } + + public void setDateOfBirth(Date dateOfBirth) { + this.dateOfBirth = CloneUtils.clone(dateOfBirth); + } + + public String getEmailAddress() { + return emailAddress; + } + + public void setEmailAddress(String emailAddress) { + this.emailAddress = emailAddress; + } + + public String getNick() { + return nick; + } + + public void setNick(String nick) { + this.nick = nick; + } + + public String getCompany() { + return company; + } + + public void setCompany(String company) { + this.company = company; + } + + + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + + + public boolean isAnonymous() { + return anonymous; + } + + public void setAnonymous(boolean anonymous) { + this.anonymous = anonymous; + } + + + public List getReviews() { + return reviews; + } + + public void setReviews(List reviews) { + this.reviews = reviews; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setDelivery(Delivery delivery) { + this.delivery = delivery; + } + + public Delivery getDelivery() { + return delivery; + } + + public void setBilling(Billing billing) { + this.billing = billing; + } + + public Billing getBilling() { + return billing; + } + + public void setGroups(List groups) { + this.groups = groups; + } + + public List getGroups() { + return groups; + } + public String getShowCustomerStateList() { + return showCustomerStateList; + } + + public void setShowCustomerStateList(String showCustomerStateList) { + this.showCustomerStateList = showCustomerStateList; + } + + public String getShowBillingStateList() { + return showBillingStateList; + } + + public void setShowBillingStateList(String showBillingStateList) { + this.showBillingStateList = showBillingStateList; + } + + public String getShowDeliveryStateList() { + return showDeliveryStateList; + } + + public void setShowDeliveryStateList(String showDeliveryStateList) { + this.showDeliveryStateList = showDeliveryStateList; + } + + public Language getDefaultLanguage() { + return defaultLanguage; + } + + public void setDefaultLanguage(Language defaultLanguage) { + this.defaultLanguage = defaultLanguage; + } + + public void setAttributes(Set attributes) { + this.attributes = attributes; + } + + public Set getAttributes() { + return attributes; + } + + public void setGender(CustomerGender gender) { + this.gender = gender; + } + + public CustomerGender getGender() { + return gender; + } + + public BigDecimal getCustomerReviewAvg() { + return customerReviewAvg; + } + + public void setCustomerReviewAvg(BigDecimal customerReviewAvg) { + this.customerReviewAvg = customerReviewAvg; + } + + public Integer getCustomerReviewCount() { + return customerReviewCount; + } + + public void setCustomerReviewCount(Integer customerReviewCount) { + this.customerReviewCount = customerReviewCount; + } + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection auditSection) { + this.auditSection = auditSection; + } + + public String getProvider() { + return provider; + } + + public void setProvider(String provider) { + this.provider = provider; + } + + public CredentialsReset getCredentialsResetRequest() { + return credentialsResetRequest; + } + + public void setCredentialsResetRequest(CredentialsReset credentialsResetRequest) { + this.credentialsResetRequest = credentialsResetRequest; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/CustomerCriteria.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/CustomerCriteria.java new file mode 100755 index 0000000000..cc05f5c312 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/CustomerCriteria.java @@ -0,0 +1,43 @@ +package com.salesmanager.core.model.customer; + +import com.salesmanager.core.model.common.Criteria; + +public class CustomerCriteria extends Criteria { + + private String firstName; + private String lastName; + private String name; + private String email; + private String country; + public String getFirstName() { + return firstName; + } + public void setFirstName(String firstName) { + this.firstName = firstName; + } + public String getLastName() { + return lastName; + } + public void setLastName(String lastName) { + this.lastName = lastName; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + public String getCountry() { + return country; + } + public void setCountry(String country) { + this.country = country; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/CustomerGender.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/CustomerGender.java new file mode 100755 index 0000000000..193f4a164b --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/CustomerGender.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.customer; + +public enum CustomerGender { + + M, F + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/CustomerList.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/CustomerList.java new file mode 100755 index 0000000000..1845f93d6d --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/CustomerList.java @@ -0,0 +1,23 @@ +package com.salesmanager.core.model.customer; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.core.model.common.EntityList; + +public class CustomerList extends EntityList { + + + /** + * + */ + private static final long serialVersionUID = -3108842276158069739L; + private List customers = new ArrayList<>(); + public void setCustomers(List customers) { + this.customers = customers; + } + public List getCustomers() { + return customers; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerAttribute.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerAttribute.java new file mode 100755 index 0000000000..d75853551b --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerAttribute.java @@ -0,0 +1,105 @@ +package com.salesmanager.core.model.customer.attribute; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.generic.SalesManagerEntity; + +@Entity +@Table(name="CUSTOMER_ATTRIBUTE", + uniqueConstraints={ + @UniqueConstraint(columnNames={ + "OPTION_ID", + "CUSTOMER_ID" + }) + } +) +public class CustomerAttribute extends SalesManagerEntity { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "CUSTOMER_ATTRIBUTE_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "CUST_ATTR_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="OPTION_ID", nullable=false) + private CustomerOption customerOption; + + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="OPTION_VALUE_ID", nullable=false) + private CustomerOptionValue customerOptionValue; + + @Column(name="CUSTOMER_ATTR_TXT_VAL") + private String textValue; + + @JsonIgnore + @ManyToOne(targetEntity = Customer.class) + @JoinColumn(name = "CUSTOMER_ID", nullable = false) + private Customer customer; + + public CustomerAttribute() { + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + + + public CustomerOption getCustomerOption() { + return customerOption; + } + + public void setCustomerOption(CustomerOption customerOption) { + this.customerOption = customerOption; + } + + public CustomerOptionValue getCustomerOptionValue() { + return customerOptionValue; + } + + public void setCustomerOptionValue(CustomerOptionValue customerOptionValue) { + this.customerOptionValue = customerOptionValue; + } + + + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + } + + public void setTextValue(String textValue) { + this.textValue = textValue; + } + + public String getTextValue() { + return textValue; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOption.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOption.java new file mode 100755 index 0000000000..e6a642691e --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOption.java @@ -0,0 +1,182 @@ +package com.salesmanager.core.model.customer.attribute; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; +import javax.validation.Valid; +import javax.validation.constraints.Pattern; + +import javax.validation.constraints.NotEmpty; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + + +@Entity +@Table(name="CUSTOMER_OPTION", indexes = { @Index(name="CUST_OPT_CODE_IDX", columnList = "CUSTOMER_OPT_CODE")}, uniqueConstraints= + @UniqueConstraint(columnNames = {"MERCHANT_ID", "CUSTOMER_OPT_CODE"})) +public class CustomerOption extends SalesManagerEntity { + private static final long serialVersionUID = -2019269055342226086L; + + @Id + @Column(name="CUSTOMER_OPTION_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "CUSTOMER_OPTION_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Column(name="SORT_ORDER") + private Integer sortOrder = 0; + + @Column(name="CUSTOMER_OPTION_TYPE", length=10) + private String customerOptionType; + + @NotEmpty + @Pattern(regexp="^[a-zA-Z0-9_]*$") + @Column(name="CUSTOMER_OPT_CODE") + //@Index(name="CUST_OPT_CODE_IDX") + private String code; + + @Column(name="CUSTOMER_OPT_ACTIVE") + private boolean active; + + @Column(name="CUSTOMER_OPT_PUBLIC") + private boolean publicOption; + + @Valid + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "customerOption") + private Set descriptions = new HashSet(); + + @Transient + private List descriptionsList = new ArrayList(); + + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore merchantStore; + + public CustomerOption() { + } + + + + public Set getDescriptions() { + return descriptions; + } + + public void setDescriptions(Set descriptions) { + this.descriptions = descriptions; + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public void setDescriptionsList(List descriptionsList) { + this.descriptionsList = descriptionsList; + } + + public List getDescriptionsList() { + return descriptionsList; + } + + + public List getDescriptionsSettoList() { + if(descriptionsList==null || descriptionsList.size()==0) { + descriptionsList = new ArrayList(this.getDescriptions()); + } + return descriptionsList; + + } + + public String getCustomerOptionType() { + return customerOptionType; + } + + + + public void setCustomerOptionType(String customerOptionType) { + this.customerOptionType = customerOptionType; + } + + + + public String getCode() { + return code; + } + + + + public void setCode(String code) { + this.code = code; + } + + + + public boolean isActive() { + return active; + } + + + + public void setActive(boolean active) { + this.active = active; + } + + + + public boolean isPublicOption() { + return publicOption; + } + + + + public void setPublicOption(boolean publicOption) { + this.publicOption = publicOption; + } + + + + public void setSortOrder(Integer sortOrder) { + this.sortOrder = sortOrder; + } + + + + public Integer getSortOrder() { + return sortOrder; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOptionDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOptionDescription.java new file mode 100755 index 0000000000..0a2ee165a8 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOptionDescription.java @@ -0,0 +1,59 @@ +package com.salesmanager.core.model.customer.attribute; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import org.hibernate.annotations.Type; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.description.Description; + +@Entity +@Table(name="CUSTOMER_OPTION_DESC", uniqueConstraints={ + @UniqueConstraint(columnNames={ + "CUSTOMER_OPTION_ID", + "LANGUAGE_ID" + }) + } +) + +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "customer_option_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +public class CustomerOptionDescription extends Description { + private static final long serialVersionUID = 1L; + + @ManyToOne(targetEntity = CustomerOption.class) + @JoinColumn(name = "CUSTOMER_OPTION_ID", nullable = false) + private CustomerOption customerOption; + + @Column(name = "CUSTOMER_OPTION_COMMENT", length=4000) + private String customerOptionComment; + + public CustomerOptionDescription() { + } + + public CustomerOption getCustomerOption() { + return customerOption; + } + + public void setCustomerOption(CustomerOption customerOption) { + this.customerOption = customerOption; + } + + public String getCustomerOptionComment() { + return customerOptionComment; + } + + public void setCustomerOptionComment(String customerOptionComment) { + this.customerOptionComment = customerOptionComment; + } + + + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOptionSet.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOptionSet.java new file mode 100755 index 0000000000..eeba334a07 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOptionSet.java @@ -0,0 +1,92 @@ +package com.salesmanager.core.model.customer.attribute; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.generic.SalesManagerEntity; + +@Entity +@Table(name="CUSTOMER_OPTION_SET", + uniqueConstraints={ + @UniqueConstraint(columnNames={ + "CUSTOMER_OPTION_ID", + "CUSTOMER_OPTION_VALUE_ID" + }) + } +) +public class CustomerOptionSet extends SalesManagerEntity { + + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "CUSTOMER_OPTIONSET_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "CUST_OPTSET_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="CUSTOMER_OPTION_ID", nullable=false) + private CustomerOption customerOption = null; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="CUSTOMER_OPTION_VALUE_ID", nullable=false) + private CustomerOptionValue customerOptionValue = null; + + + + @Column(name="SORT_ORDER") + private Integer sortOrder = new Integer(0); + + + + public int getSortOrder() { + return sortOrder; + } + + public void setSortOrder(int sortOrder) { + this.sortOrder = sortOrder; + } + + public void setCustomerOptionValue(CustomerOptionValue customerOptionValue) { + this.customerOptionValue = customerOptionValue; + } + + public CustomerOptionValue getCustomerOptionValue() { + return customerOptionValue; + } + + public void setCustomerOption(CustomerOption customerOption) { + this.customerOption = customerOption; + } + + public CustomerOption getCustomerOption() { + return customerOption; + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOptionType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOptionType.java new file mode 100755 index 0000000000..99bafb5458 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOptionType.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.customer.attribute; + +public enum CustomerOptionType { + + Text, Radio, Select, Checkbox + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOptionValue.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOptionValue.java new file mode 100755 index 0000000000..e945866722 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOptionValue.java @@ -0,0 +1,152 @@ +package com.salesmanager.core.model.customer.attribute; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; +import javax.validation.Valid; +import javax.validation.constraints.Pattern; + +import javax.validation.constraints.NotEmpty; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + + +@Entity +@Table(name="CUSTOMER_OPTION_VALUE", indexes = { @Index(name="CUST_OPT_VAL_CODE_IDX",columnList = "CUSTOMER_OPT_VAL_CODE")}, uniqueConstraints= + @UniqueConstraint(columnNames = {"MERCHANT_ID", "CUSTOMER_OPT_VAL_CODE"})) +public class CustomerOptionValue extends SalesManagerEntity { + private static final long serialVersionUID = 3736085877929910891L; + + @Id + @Column(name="CUSTOMER_OPTION_VALUE_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "CUSTOMER_OPT_VAL_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Column(name="SORT_ORDER") + private Integer sortOrder = 0; + + @Column(name="CUSTOMER_OPT_VAL_IMAGE") + private String customerOptionValueImage; + + @NotEmpty + @Pattern(regexp="^[a-zA-Z0-9_]*$") + @Column(name="CUSTOMER_OPT_VAL_CODE") + private String code; + + + @Valid + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "customerOptionValue") + private Set descriptions = new HashSet(); + + @Transient + private List descriptionsList = new ArrayList(); + + @JsonIgnore + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore merchantStore; + + public CustomerOptionValue() { + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + + public Set getDescriptions() { + return descriptions; + } + + public void setDescriptions(Set descriptions) { + this.descriptions = descriptions; + } + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public void setDescriptionsList(List descriptionsList) { + this.descriptionsList = descriptionsList; + } + + public List getDescriptionsList() { + return descriptionsList; + } + + public List getDescriptionsSettoList() { + if(descriptionsList==null || descriptionsList.size()==0) { + descriptionsList = new ArrayList(this.getDescriptions()); + } + return descriptionsList; + } + + //public void setImage(MultipartFile image) { + // this.image = image; + //} + + //public MultipartFile getImage() { + // return image; + //} + + + public String getCustomerOptionValueImage() { + return customerOptionValueImage; + } + + public void setCustomerOptionValueImage(String customerOptionValueImage) { + this.customerOptionValueImage = customerOptionValueImage; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + + public void setSortOrder(Integer sortOrder) { + this.sortOrder = sortOrder; + } + + public Integer getSortOrder() { + return sortOrder; + } + + + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOptionValueDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOptionValueDescription.java new file mode 100755 index 0000000000..b90b6bad83 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/attribute/CustomerOptionValueDescription.java @@ -0,0 +1,46 @@ +package com.salesmanager.core.model.customer.attribute; + +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.description.Description; + +@Entity +@Table(name = "CUSTOMER_OPT_VAL_DESCRIPTION", uniqueConstraints={ + @UniqueConstraint(columnNames={ + "CUSTOMER_OPT_VAL_ID", + "LANGUAGE_ID" + }) + } +) + +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "customer_option_value_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +//@SequenceGenerator(name = "description_gen", sequenceName = "customer_option_value_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_SEQUENCE_START) +public class CustomerOptionValueDescription extends Description { + private static final long serialVersionUID = 1L; + + @JsonIgnore + @ManyToOne(targetEntity = CustomerOptionValue.class) + @JoinColumn(name = "CUSTOMER_OPT_VAL_ID") + private CustomerOptionValue customerOptionValue; + + + public CustomerOptionValueDescription() { + } + + public CustomerOptionValue getCustomerOptionValue() { + return customerOptionValue; + } + + public void setCustomerOptionValue(CustomerOptionValue customerOptionValue) { + this.customerOptionValue = customerOptionValue; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/connection/AbstractUserConnection.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/connection/AbstractUserConnection.java new file mode 100755 index 0000000000..050416e795 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/connection/AbstractUserConnection.java @@ -0,0 +1,105 @@ +package com.salesmanager.core.model.customer.connection; + +import java.io.Serializable; + +import javax.persistence.MappedSuperclass; + + +@Deprecated +@MappedSuperclass +public abstract class AbstractUserConnection

implements RemoteUser, + Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String accessToken; + private String displayName; + private Long expireTime; + private String imageUrl; + private String profileUrl; + private int userRank; + private String refreshToken; + private String secret; + + + public String getAccessToken() { + return accessToken; + } + + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public Long getExpireTime() { + return expireTime; + } + + public void setExpireTime(Long expireTime) { + this.expireTime = expireTime; + } + + public String getImageUrl() { + return imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + + public String getProfileUrl() { + return profileUrl; + } + + public void setProfileUrl(String profileUrl) { + this.profileUrl = profileUrl; + } + + public abstract String getProviderId(); + + public abstract void setProviderId(String providerId); + + public abstract String getProviderUserId(); + + public abstract void setProviderUserId(String providerUserId); + + public int getRank() { + return userRank; + } + + public void setRank(int userRank) { + this.userRank = userRank; + } + + public String getRefreshToken() { + return refreshToken; + } + + public void setRefreshToken(String refreshToken) { + this.refreshToken = refreshToken; + } + + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } + + public abstract String getUserId(); + + public abstract void setUserId(String userId); + + protected abstract P getId(); +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/connection/AbstractUserConnectionWithCompositeKey.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/connection/AbstractUserConnectionWithCompositeKey.java new file mode 100755 index 0000000000..8ce070f637 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/connection/AbstractUserConnectionWithCompositeKey.java @@ -0,0 +1,60 @@ +package com.salesmanager.core.model.customer.connection; + +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import com.salesmanager.core.constants.SchemaConstant; + +@Deprecated +@MappedSuperclass +@Table(name="USERCONNECTION", uniqueConstraints = { @UniqueConstraint(columnNames = { "userId", + "providerId", "userRank" }) }) +public abstract class AbstractUserConnectionWithCompositeKey extends + AbstractUserConnection { + + @Id + private UserConnectionPK primaryKey = new UserConnectionPK(); + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Override + public String getProviderId() { + return primaryKey.getProviderId(); + } + + @Override + public void setProviderId(String providerId) { + primaryKey.setProviderId(providerId); + } + + @Override + public String getProviderUserId() { + return primaryKey.getProviderUserId(); + } + + @Override + public void setProviderUserId(String providerUserId) { + primaryKey.setProviderUserId(providerUserId); + } + + @Override + public String getUserId() { + return primaryKey.getUserId(); + } + + @Override + public void setUserId(String userId) { + primaryKey.setUserId(userId); + } + + @Override + protected UserConnectionPK getId() { + return primaryKey; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/connection/RemoteUser.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/connection/RemoteUser.java new file mode 100755 index 0000000000..aebac706d6 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/connection/RemoteUser.java @@ -0,0 +1,54 @@ +package com.salesmanager.core.model.customer.connection; + +//import org.springframework.social.UserIdSource; + +@Deprecated +public interface RemoteUser { //extends UserIdSource{ + + public String getUserId(); + + public void setUserId(String id); + /* + * Provider identifier: Facebook, Twitter, LinkedIn etc + */ + public String getProviderUserId(); + + public void setProviderUserId(String provider); + + public String getProviderId(); + + public void setProviderId(String providerId); + + public int getRank(); + + public void setRank(int rank); + + public String getSecret(); + + public void setSecret(String secret); + + public String getDisplayName(); + + public void setDisplayName(String displayName); + + public String getProfileUrl(); + + public void setProfileUrl(String profileUrl); + + public String getImageUrl(); + + public void setImageUrl(String imageUrl); + + public String getAccessToken(); + + public void setAccessToken(String accessToken); + + public String getRefreshToken(); + + public void setRefreshToken(String refreshToken); + + public Long getExpireTime(); + + public void setExpireTime(Long expireTime); + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/connection/UserConnection.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/connection/UserConnection.java new file mode 100755 index 0000000000..797b1eec3c --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/connection/UserConnection.java @@ -0,0 +1,15 @@ +package com.salesmanager.core.model.customer.connection; + +import javax.persistence.Entity; + +@Deprecated +@Entity +public class UserConnection extends AbstractUserConnectionWithCompositeKey { + + /** + * + */ + private static final long serialVersionUID = 1L; + + +} \ No newline at end of file diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/connection/UserConnectionPK.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/connection/UserConnectionPK.java new file mode 100755 index 0000000000..55e71a2855 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/connection/UserConnectionPK.java @@ -0,0 +1,64 @@ +package com.salesmanager.core.model.customer.connection; + +import java.io.Serializable; + +import javax.persistence.Embeddable; + +/** + * Identity key for storing spring social objects + * @author carlsamson + * + */ +@Deprecated +@Embeddable +public class UserConnectionPK implements Serializable { + /** + * + */ + private static final long serialVersionUID = 1L; + + private String userId; + private String providerId; + private String providerUserId; + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getProviderId() { + return providerId; + } + + public void setProviderId(String providerId) { + this.providerId = providerId; + } + + public String getProviderUserId() { + return providerUserId; + } + + public void setProviderUserId(String providerUserId) { + this.providerUserId = providerUserId; + } + + public boolean equals(Object o) { + if (o instanceof UserConnectionPK) { + UserConnectionPK other = (UserConnectionPK) o; + return other.getProviderId().equals(getProviderId()) + && other.getProviderUserId().equals(getProviderUserId()) + && other.getUserId().equals(getUserId()); + } else { + return false; + } + } + + public int hashCode() { + return getUserId().hashCode() + getProviderId().hashCode() + + getProviderUserId().hashCode(); + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/review/CustomerReview.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/review/CustomerReview.java new file mode 100755 index 0000000000..8e15e85f29 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/review/CustomerReview.java @@ -0,0 +1,159 @@ +package com.salesmanager.core.model.customer.review; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.UniqueConstraint; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.generic.SalesManagerEntity; + +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "CUSTOMER_REVIEW", uniqueConstraints={ + @UniqueConstraint(columnNames={ + "CUSTOMERS_ID", + "REVIEWED_CUSTOMER_ID" + }) + } +) +public class CustomerReview extends SalesManagerEntity implements Auditable { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "CUSTOMER_REVIEW_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", + pkColumnValue = "CUSTOMER_REVIEW_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Embedded + private AuditSection audit = new AuditSection(); + + @Column(name = "REVIEWS_RATING") + private Double reviewRating; + + @Column(name = "REVIEWS_READ") + private Long reviewRead; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "REVIEW_DATE") + private Date reviewDate; + + @Column(name = "STATUS") + private Integer status; + + @ManyToOne + @JoinColumn(name="CUSTOMERS_ID") + private Customer customer; + + + + @OneToOne + @JoinColumn(name="REVIEWED_CUSTOMER_ID") + private Customer reviewedCustomer; + + public Customer getReviewedCustomer() { + return reviewedCustomer; + } + + public void setReviewedCustomer(Customer reviewedCustomer) { + this.reviewedCustomer = reviewedCustomer; + } + + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "customerReview") + private Set descriptions = new HashSet(); + + public CustomerReview() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Double getReviewRating() { + return reviewRating; + } + + public void setReviewRating(Double reviewRating) { + this.reviewRating = reviewRating; + } + + public Long getReviewRead() { + return reviewRead; + } + + public void setReviewRead(Long reviewRead) { + this.reviewRead = reviewRead; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + } + + + public Set getDescriptions() { + return descriptions; + } + + public void setDescriptions(Set descriptions) { + this.descriptions = descriptions; + } + + @Override + public AuditSection getAuditSection() { + return audit; + } + + @Override + public void setAuditSection(AuditSection audit) { + this.audit = audit; + } + + public Date getReviewDate() { + return reviewDate; + } + + public void setReviewDate(Date reviewDate) { + this.reviewDate = reviewDate; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/customer/review/CustomerReviewDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/review/CustomerReviewDescription.java new file mode 100755 index 0000000000..9f21b34bc8 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/customer/review/CustomerReviewDescription.java @@ -0,0 +1,63 @@ +/* + * Licensed to csti consulting + * You may obtain a copy of the License at + * + * http://www.csticonsulting.com + * Copyright (c) 2006-Aug 24, 2010 Consultation CS-TI inc. + * + * 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 com.salesmanager.core.model.customer.review; + +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.description.Description; +import com.salesmanager.core.model.reference.language.Language; + +@Entity +@Table(name = "CUSTOMER_REVIEW_DESCRIPTION", uniqueConstraints={ + @UniqueConstraint(columnNames={ + "CUSTOMER_REVIEW_ID", + "LANGUAGE_ID" + }) +}) + +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "custome_review_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +//@SequenceGenerator(name = "description_gen", sequenceName = "custome_review_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_SEQUENCE_START) +public class CustomerReviewDescription extends Description { + private static final long serialVersionUID = 1L; + + @ManyToOne(targetEntity = CustomerReview.class) + @JoinColumn(name="CUSTOMER_REVIEW_ID") + private CustomerReview customerReview; + + public CustomerReview getCustomerReview() { + return customerReview; + } + + public void setCustomerReview(CustomerReview customerReview) { + this.customerReview = customerReview; + } + + public CustomerReviewDescription() { + } + + public CustomerReviewDescription(Language language, String name) { + this.setLanguage(language); + this.setName(name); + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/generic/SalesManagerEntity.java b/sm-core-model/src/main/java/com/salesmanager/core/model/generic/SalesManagerEntity.java new file mode 100755 index 0000000000..110e155496 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/generic/SalesManagerEntity.java @@ -0,0 +1,105 @@ +package com.salesmanager.core.model.generic; + +import java.io.Serializable; +import java.text.Collator; +import java.util.Locale; + +import org.hibernate.Hibernate; + + +/** + *

Entité racine pour la persistence des objets via JPA.

+ * + * @param type de l'entité + */ +public abstract class SalesManagerEntity, E extends SalesManagerEntity> + implements Serializable, Comparable { + + private static final long serialVersionUID = -3988499137919577054L; + + public static final Collator DEFAULT_STRING_COLLATOR = Collator.getInstance(Locale.FRENCH); + + static { + DEFAULT_STRING_COLLATOR.setStrength(Collator.PRIMARY); + } + + /** + * Retourne la valeur de l'identifiant unique. + * + * @return id + */ + public abstract K getId(); + + /** + * Définit la valeur de l'identifiant unique. + * + * @param id id + */ + public abstract void setId(K id); + + /** + * Indique si l'objet a déjà été persisté ou non + * + * @return vrai si l'objet n'a pas encore été persisté + */ + public boolean isNew() { + return getId() == null; + } + + + @SuppressWarnings("unchecked") + @Override + public boolean equals(Object object) { + if (object == null) { + return false; + } + if (object == this) { + return true; + } + + // l'objet peut être proxyfié donc on utilise Hibernate.getClass() pour sortir la vraie classe + if (Hibernate.getClass(object) != Hibernate.getClass(this)) { + return false; + } + + SalesManagerEntity entity = (SalesManagerEntity) object; // NOSONAR : traité au-dessus mais wrapper Hibernate + K id = getId(); + + if (id == null) { + return false; + } + + return id.equals(entity.getId()); + } + + @Override + public int hashCode() { + int hash = 7; + + K id = getId(); + hash = 31 * hash + ((id == null) ? 0 : id.hashCode()); + + return hash; + } + + public int compareTo(E o) { + if (this == o) { + return 0; + } + return this.getId().compareTo(o.getId()); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("entity."); + builder.append(Hibernate.getClass(this).getSimpleName()); + builder.append("<"); + builder.append(getId()); + builder.append("-"); + builder.append(super.toString()); + builder.append(">"); + + return builder.toString(); + } +} \ No newline at end of file diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/merchant/MerchantStore.java b/sm-core-model/src/main/java/com/salesmanager/core/model/merchant/MerchantStore.java new file mode 100755 index 0000000000..007076aebc --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/merchant/MerchantStore.java @@ -0,0 +1,427 @@ +package com.salesmanager.core.model.merchant; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Transient; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Pattern; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.MeasureUnit; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.currency.Currency; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.core.utils.CloneUtils; + +@Entity +@Table(name = "MERCHANT_STORE", + indexes = @Index(columnList = "LINEAGE")) +public class MerchantStore extends SalesManagerEntity implements Auditable { + + private static final long serialVersionUID = 1L; + + public final static String DEFAULT_STORE = "DEFAULT"; + + public MerchantStore(Integer id, String code, String name) { + this.id = id; + this.code = code; + this.storename = name; + + } + + public MerchantStore(Integer id, String code, String name, String storeEmailAddress) { + this.id = id; + this.code = code; + this.storename = name; + this.storeEmailAddress = storeEmailAddress; + } + + + + @Id + @Column(name = "MERCHANT_ID", unique = true, nullable = false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "STORE_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Integer id; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @JsonIgnore + @ManyToOne + @JoinColumn(name = "PARENT_ID") + private MerchantStore parent; + + @JsonIgnore + @OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE) + private Set stores = new HashSet(); + + @Column(name = "IS_RETAILER") + private Boolean retailer = false; + + @NotEmpty + @Column(name = "STORE_NAME", nullable = false, length = 100) + private String storename; + + @NotEmpty + @Pattern(regexp = "^[a-zA-Z0-9_]*$") + @Column(name = "STORE_CODE", nullable = false, unique = true, length = 100) + private String code; + + @Column(name = "LINEAGE") + private String lineage; + + @NotEmpty + @Column(name = "STORE_PHONE", length = 50) + private String storephone; + + @Column(name = "STORE_ADDRESS") + private String storeaddress; + + @NotEmpty + @Column(name = "STORE_CITY", length = 100) + private String storecity; + + @NotEmpty + @Column(name = "STORE_POSTAL_CODE", length = 15) + private String storepostalcode; + + @JsonIgnore + @ManyToOne(fetch = FetchType.LAZY, targetEntity = Country.class) + @JoinColumn(name = "COUNTRY_ID", nullable = false, updatable = true) + private Country country; + + @JsonIgnore + @ManyToOne(fetch = FetchType.LAZY, targetEntity = Zone.class) + @JoinColumn(name = "ZONE_ID", nullable = true, updatable = true) + private Zone zone; + + @Column(name = "STORE_STATE_PROV", length = 100) + private String storestateprovince; + + @Column(name = "WEIGHTUNITCODE", length = 5) + private String weightunitcode = MeasureUnit.LB.name(); + + @Column(name = "SEIZEUNITCODE", length = 5) + private String seizeunitcode = MeasureUnit.IN.name(); + + @Temporal(TemporalType.DATE) + @Column(name = "IN_BUSINESS_SINCE") + private Date inBusinessSince = new Date(); + + @Transient + private String dateBusinessSince; + + @JsonIgnore + @ManyToOne(fetch = FetchType.LAZY, targetEntity = Language.class) + @JoinColumn(name = "LANGUAGE_ID", nullable = false) + private Language defaultLanguage; + + @JsonIgnore + @NotEmpty + @ManyToMany(fetch = FetchType.LAZY) + @JoinTable(name = "MERCHANT_LANGUAGE") + private List languages = new ArrayList(); + + @Column(name = "USE_CACHE") + private boolean useCache = false; + + @Column(name = "STORE_TEMPLATE", length = 25) + private String storeTemplate; + + @Column(name = "INVOICE_TEMPLATE", length = 25) + private String invoiceTemplate; + + @Column(name = "DOMAIN_NAME", length = 80) + private String domainName; + + @JsonIgnore + @Column(name = "CONTINUESHOPPINGURL", length = 150) + private String continueshoppingurl; + + @Email + @NotEmpty + @Column(name = "STORE_EMAIL", length = 60, nullable = false) + private String storeEmailAddress; + + @JsonIgnore + @Column(name = "STORE_LOGO", length = 100) + private String storeLogo; + + @JsonIgnore + @ManyToOne(fetch = FetchType.LAZY, targetEntity = Currency.class) + @JoinColumn(name = "CURRENCY_ID", nullable = false) + private Currency currency; + + @Column(name = "CURRENCY_FORMAT_NATIONAL") + private boolean currencyFormatNational; + + public MerchantStore() { + } + + public boolean isUseCache() { + return useCache; + } + + public void setUseCache(boolean useCache) { + this.useCache = useCache; + } + + @Override + public void setId(Integer id) { + this.id = id; + } + + @Override + public Integer getId() { + return this.id; + } + + public String getStorename() { + return storename; + } + + public void setStorename(String storename) { + this.storename = storename; + } + + public String getStorephone() { + return storephone; + } + + public void setStorephone(String storephone) { + this.storephone = storephone; + } + + public String getStoreaddress() { + return storeaddress; + } + + public void setStoreaddress(String storeaddress) { + this.storeaddress = storeaddress; + } + + public String getStorecity() { + return storecity; + } + + public void setStorecity(String storecity) { + this.storecity = storecity; + } + + public String getStorepostalcode() { + return storepostalcode; + } + + public void setStorepostalcode(String storepostalcode) { + this.storepostalcode = storepostalcode; + } + + public Country getCountry() { + return country; + } + + public void setCountry(Country country) { + this.country = country; + } + + public Zone getZone() { + return zone; + } + + public void setZone(Zone zone) { + this.zone = zone; + } + + public String getStorestateprovince() { + return storestateprovince; + } + + public void setStorestateprovince(String storestateprovince) { + this.storestateprovince = storestateprovince; + } + + public Currency getCurrency() { + return currency; + } + + public void setCurrency(Currency currency) { + this.currency = currency; + } + + public String getWeightunitcode() { + return weightunitcode; + } + + public void setWeightunitcode(String weightunitcode) { + this.weightunitcode = weightunitcode; + } + + public String getSeizeunitcode() { + return seizeunitcode; + } + + public void setSeizeunitcode(String seizeunitcode) { + this.seizeunitcode = seizeunitcode; + } + + public Date getInBusinessSince() { + return CloneUtils.clone(inBusinessSince); + } + + public void setInBusinessSince(Date inBusinessSince) { + this.inBusinessSince = CloneUtils.clone(inBusinessSince); + } + + public Language getDefaultLanguage() { + return defaultLanguage; + } + + public void setDefaultLanguage(Language defaultLanguage) { + this.defaultLanguage = defaultLanguage; + } + + public List getLanguages() { + return languages; + } + + public void setLanguages(List languages) { + this.languages = languages; + } + + public String getStoreLogo() { + return storeLogo; + } + + public void setStoreLogo(String storeLogo) { + this.storeLogo = storeLogo; + } + + public String getStoreTemplate() { + return storeTemplate; + } + + public void setStoreTemplate(String storeTemplate) { + this.storeTemplate = storeTemplate; + } + + public String getInvoiceTemplate() { + return invoiceTemplate; + } + + public void setInvoiceTemplate(String invoiceTemplate) { + this.invoiceTemplate = invoiceTemplate; + } + + public String getDomainName() { + return domainName; + } + + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + public String getContinueshoppingurl() { + return continueshoppingurl; + } + + public void setContinueshoppingurl(String continueshoppingurl) { + this.continueshoppingurl = continueshoppingurl; + } + + public String getStoreEmailAddress() { + return storeEmailAddress; + } + + public void setStoreEmailAddress(String storeEmailAddress) { + this.storeEmailAddress = storeEmailAddress; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public void setDateBusinessSince(String dateBusinessSince) { + this.dateBusinessSince = dateBusinessSince; + } + + public String getDateBusinessSince() { + return dateBusinessSince; + } + + public void setCurrencyFormatNational(boolean currencyFormatNational) { + this.currencyFormatNational = currencyFormatNational; + } + + public boolean isCurrencyFormatNational() { + return currencyFormatNational; + } + + @Override + public AuditSection getAuditSection() { + return this.auditSection; + } + + @Override + public void setAuditSection(AuditSection audit) { + this.auditSection = audit; + + } + + public MerchantStore getParent() { + return parent; + } + + public void setParent(MerchantStore parent) { + this.parent = parent; + } + + public Set getStores() { + return stores; + } + + public void setStores(Set stores) { + this.stores = stores; + } + + public Boolean isRetailer() { + return retailer; + } + + + public void setRetailer(Boolean retailer) { + this.retailer = retailer; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/merchant/MerchantStoreCriteria.java b/sm-core-model/src/main/java/com/salesmanager/core/model/merchant/MerchantStoreCriteria.java new file mode 100755 index 0000000000..1e041ba0e4 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/merchant/MerchantStoreCriteria.java @@ -0,0 +1,29 @@ +package com.salesmanager.core.model.merchant; + +import com.salesmanager.core.model.common.Criteria; + +public class MerchantStoreCriteria extends Criteria { + + private boolean retailers = false; + private boolean stores = false; + + public boolean isRetailers() { + return retailers; + } + + public void setRetailers(boolean retailers) { + this.retailers = retailers; + } + + public boolean isStores() { + return stores; + } + + public void setStores(boolean stores) { + this.stores = stores; + } + + + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/Order.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/Order.java new file mode 100755 index 0000000000..422ff2b8d8 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/Order.java @@ -0,0 +1,409 @@ +package com.salesmanager.core.model.order; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.Locale; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.validation.Valid; + +import org.hibernate.annotations.OrderBy; +import org.hibernate.annotations.Type; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.model.common.Billing; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.attributes.OrderAttribute; +import com.salesmanager.core.model.order.orderproduct.OrderProduct; +import com.salesmanager.core.model.order.orderstatus.OrderStatus; +import com.salesmanager.core.model.order.orderstatus.OrderStatusHistory; +import com.salesmanager.core.model.order.payment.CreditCard; +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.core.model.reference.currency.Currency; +import com.salesmanager.core.utils.CloneUtils; + +@Entity +@Table (name="ORDERS") +public class Order extends SalesManagerEntity { + + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + @Column (name ="ORDER_ID" , unique=true , nullable=false ) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", + pkColumnValue = "ORDER_ID_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Column (name ="ORDER_STATUS") + @Enumerated(value = EnumType.STRING) + private OrderStatus status; + + @Temporal(TemporalType.TIMESTAMP) + @Column (name ="LAST_MODIFIED") + private Date lastModified; + + //the customer object can be detached. An order can exist and the customer deleted + @Column (name ="CUSTOMER_ID") + private Long customerId; + + @Temporal(TemporalType.DATE) + @Column (name ="DATE_PURCHASED") + private Date datePurchased; + + //used for an order payable on multiple installment + @Temporal(TemporalType.TIMESTAMP) + @Column (name ="ORDER_DATE_FINISHED") + private Date orderDateFinished; + + //What was the exchange rate + @Column (name ="CURRENCY_VALUE") + private BigDecimal currencyValue = new BigDecimal(1);//default 1-1 + + @Column (name ="ORDER_TOTAL") + private BigDecimal total; + + @Column (name ="IP_ADDRESS") + private String ipAddress; + + @Column(name = "CART_CODE", nullable=true) + private String shoppingCartCode; + + @Column (name ="CHANNEL") + @Enumerated(value = EnumType.STRING) + private OrderChannel channel; + + @Column (name ="ORDER_TYPE") + @Enumerated(value = EnumType.STRING) + private OrderType orderType = OrderType.ORDER; + + @Column (name ="PAYMENT_TYPE") + @Enumerated(value = EnumType.STRING) + private PaymentType paymentType; + + @Column (name ="PAYMENT_MODULE_CODE") + private String paymentModuleCode; + + @Column (name ="SHIPPING_MODULE_CODE") + private String shippingModuleCode; + + @Column(name = "CUSTOMER_AGREED") + private Boolean customerAgreement = false; + + @Column(name = "CONFIRMED_ADDRESS") + private Boolean confirmedAddress = false; + + @Embedded + private Delivery delivery = null; + + @Valid + @Embedded + private Billing billing = null; + + @Embedded + @Deprecated + private CreditCard creditCard = null; + + + @ManyToOne(targetEntity = Currency.class) + @JoinColumn(name = "CURRENCY_ID") + private Currency currency; + + @Type(type="locale") + @Column (name ="LOCALE") + private Locale locale; + + + @JsonIgnore + @ManyToOne(targetEntity = MerchantStore.class) + @JoinColumn(name="MERCHANTID") + private MerchantStore merchant; + + //@OneToMany(mappedBy = "order") + //private Set orderAccounts = new HashSet(); + + @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) + private Set orderProducts = new LinkedHashSet(); + + @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) + @OrderBy(clause = "sort_order asc") + private Set orderTotal = new LinkedHashSet(); + + @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) + @OrderBy(clause = "ORDER_STATUS_HISTORY_ID asc") + private Set orderHistory = new LinkedHashSet(); + + @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) + private Set orderAttributes = new LinkedHashSet(); + + public Order() { + } + + @Column (name ="CUSTOMER_EMAIL_ADDRESS", length=50, nullable=false) + private String customerEmailAddress; + + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public OrderStatus getStatus() { + return status; + } + + public void setStatus(OrderStatus status) { + this.status = status; + } + + public Date getLastModified() { + return CloneUtils.clone(lastModified); + } + + public void setLastModified(Date lastModified) { + this.lastModified = CloneUtils.clone(lastModified); + } + + public Date getDatePurchased() { + return CloneUtils.clone(datePurchased); + } + + public void setDatePurchased(Date datePurchased) { + this.datePurchased = CloneUtils.clone(datePurchased); + } + + public Date getOrderDateFinished() { + return CloneUtils.clone(orderDateFinished); + } + + public void setOrderDateFinished(Date orderDateFinished) { + this.orderDateFinished = CloneUtils.clone(orderDateFinished); + } + + public BigDecimal getCurrencyValue() { + return currencyValue; + } + + public void setCurrencyValue(BigDecimal currencyValue) { + this.currencyValue = currencyValue; + } + + public BigDecimal getTotal() { + return total; + } + + public void setTotal(BigDecimal total) { + this.total = total; + } + + + public String getIpAddress() { + return ipAddress; + } + + public void setIpAddress(String ipAddress) { + this.ipAddress = ipAddress; + } + + + public String getPaymentModuleCode() { + return paymentModuleCode; + } + + public void setPaymentModuleCode(String paymentModuleCode) { + this.paymentModuleCode = paymentModuleCode; + } + + + + public String getShippingModuleCode() { + return shippingModuleCode; + } + + public void setShippingModuleCode(String shippingModuleCode) { + this.shippingModuleCode = shippingModuleCode; + } + + + + public Currency getCurrency() { + return currency; + } + + public void setCurrency(Currency currency) { + this.currency = currency; + } + + public MerchantStore getMerchant() { + return merchant; + } + + public void setMerchant(MerchantStore merchant) { + this.merchant = merchant; + } + + public Set getOrderProducts() { + return orderProducts; + } + + public void setOrderProducts(Set orderProducts) { + this.orderProducts = orderProducts; + } + + public Set getOrderTotal() { + return orderTotal; + } + + public void setOrderTotal(Set orderTotal) { + this.orderTotal = orderTotal; + } + + public Set getOrderHistory() { + return orderHistory; + } + + public void setOrderHistory(Set orderHistory) { + this.orderHistory = orderHistory; + } + + + public void setDelivery(Delivery delivery) { + this.delivery = delivery; + } + + public Delivery getDelivery() { + return delivery; + } + + public void setBilling(Billing billing) { + this.billing = billing; + } + + public Billing getBilling() { + return billing; + } + + public Long getCustomerId() { + return customerId; + } + + public void setCustomerId(Long customerId) { + this.customerId = customerId; + } + + + public String getCustomerEmailAddress() { + return customerEmailAddress; + } + + public void setCustomerEmailAddress(String customerEmailAddress) { + this.customerEmailAddress = customerEmailAddress; + } + + + public void setChannel(OrderChannel channel) { + this.channel = channel; + } + + + public OrderChannel getChannel() { + return channel; + } + + + public void setCreditCard(CreditCard creditCard) { + this.creditCard = creditCard; + } + + + public CreditCard getCreditCard() { + return creditCard; + } + + + public void setPaymentType(PaymentType paymentType) { + this.paymentType = paymentType; + } + + + public PaymentType getPaymentType() { + return paymentType; + } + + public OrderType getOrderType() { + return orderType; + } + + public void setOrderType(OrderType orderType) { + this.orderType = orderType; + } + + public Locale getLocale() { + return locale; + } + + public void setLocale(Locale locale) { + this.locale = locale; + } + + public Boolean getCustomerAgreement() { + return customerAgreement; + } + + public void setCustomerAgreement(Boolean customerAgreement) { + this.customerAgreement = customerAgreement; + } + + public Boolean getConfirmedAddress() { + return confirmedAddress; + } + + public void setConfirmedAddress(Boolean confirmedAddress) { + this.confirmedAddress = confirmedAddress; + } + + public Set getOrderAttributes() { + return orderAttributes; + } + + public void setOrderAttributes(Set orderAttributes) { + this.orderAttributes = orderAttributes; + } + + public String getShoppingCartCode() { + return shoppingCartCode; + } + + public void setShoppingCartCode(String shoppingCartCode) { + this.shoppingCartCode = shoppingCartCode; + } + +} \ No newline at end of file diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderChannel.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderChannel.java new file mode 100755 index 0000000000..a670cff088 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderChannel.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.order; + +public enum OrderChannel { + + ONLINE, API + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderCriteria.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderCriteria.java new file mode 100755 index 0000000000..c9f9110ae8 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderCriteria.java @@ -0,0 +1,63 @@ +package com.salesmanager.core.model.order; + +import com.salesmanager.core.model.common.Criteria; + +public class OrderCriteria extends Criteria { + + private String customerName = null; + private String customerPhone = null; + private String status = null; + private Long id = null; + private String paymentMethod; + private Long customerId; + private String email; + public void setPaymentMethod(String paymentMethod) { + this.paymentMethod = paymentMethod; + } + public String getPaymentMethod() { + return paymentMethod; + } + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + public String getCustomerName() { + return customerName; + } + public Long getCustomerId() + { + return customerId; + } + public void setCustomerId( Long customerId ) + { + this.customerId = customerId; + } + public String getCustomerPhone() { + return customerPhone; + } + public void setCustomerPhone(String customerPhone) { + this.customerPhone = customerPhone; + } + public String getStatus() { + return status; + } + public void setStatus(String status) { + this.status = status; + } + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + + + + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderList.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderList.java new file mode 100755 index 0000000000..da9033e4db --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderList.java @@ -0,0 +1,23 @@ +package com.salesmanager.core.model.order; + +import java.util.List; + +import com.salesmanager.core.model.common.EntityList; + +public class OrderList extends EntityList { + + /** + * + */ + private static final long serialVersionUID = -6645927228659963628L; + private List orders; + + public void setOrders(List orders) { + this.orders = orders; + } + + public List getOrders() { + return orders; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderSummary.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderSummary.java new file mode 100755 index 0000000000..5e743ac4b8 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderSummary.java @@ -0,0 +1,54 @@ +package com.salesmanager.core.model.order; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.core.model.shipping.ShippingSummary; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; + + +/** + * This object is used as input object for many services + * such as order total calculation and tax calculation + * @author Carl Samson + * + */ +public class OrderSummary implements Serializable { + + + /** + * + */ + private static final long serialVersionUID = 1L; + private OrderSummaryType orderSummaryType = OrderSummaryType.ORDERTOTAL; + private ShippingSummary shippingSummary; + private String promoCode; + private List products = new ArrayList(); + + public void setProducts(List products) { + this.products = products; + } + public List getProducts() { + return products; + } + public void setShippingSummary(ShippingSummary shippingSummary) { + this.shippingSummary = shippingSummary; + } + public ShippingSummary getShippingSummary() { + return shippingSummary; + } + public OrderSummaryType getOrderSummaryType() { + return orderSummaryType; + } + public void setOrderSummaryType(OrderSummaryType orderSummaryType) { + this.orderSummaryType = orderSummaryType; + } + public String getPromoCode() { + return promoCode; + } + public void setPromoCode(String promoCode) { + this.promoCode = promoCode; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderSummaryType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderSummaryType.java new file mode 100755 index 0000000000..5b16f8059d --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderSummaryType.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.order; + +public enum OrderSummaryType { + + SHOPPINGCART, ORDERTOTAL + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotal.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotal.java new file mode 100755 index 0000000000..83a8d884e2 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotal.java @@ -0,0 +1,157 @@ +package com.salesmanager.core.model.order; + +import java.math.BigDecimal; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import org.hibernate.annotations.Type; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.generic.SalesManagerEntity; + + +/** + * Order line items related to an order. + * @author casams1 + * + */ + +@Entity +@Table (name="ORDER_TOTAL" ) +public class OrderTotal extends SalesManagerEntity { + private static final long serialVersionUID = -5885315557404081674L; + + @Id + @Column(name = "ORDER_ACCOUNT_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "ORDER_TOTAL_ID_NEXT_VALUE") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Column (name ="CODE", nullable=false) + private String orderTotalCode;//SHIPPING, TAX + + @Column (name ="TITLE", nullable=true) + private String title; + + @Column (name ="TEXT", nullable=true) + @Type(type = "org.hibernate.type.TextType") + private String text; + + @Column (name ="VALUE", precision=15, scale=4, nullable=false ) + private BigDecimal value; + + @Column (name ="MODULE", length=60 , nullable=true ) + private String module; + + @Column (name ="ORDER_VALUE_TYPE") + @Enumerated(value = EnumType.STRING) + private OrderValueType orderValueType = OrderValueType.ONE_TIME; + + @Column (name ="ORDER_TOTAL_TYPE") + @Enumerated(value = EnumType.STRING) + private OrderTotalType orderTotalType = null; + + @Column (name ="SORT_ORDER", nullable=false) + private int sortOrder; + + @JsonIgnore + @ManyToOne(targetEntity = Order.class) + @JoinColumn(name = "ORDER_ID", nullable=false) + private Order order; + + public OrderTotal() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public BigDecimal getValue() { + return value; + } + + public void setValue(BigDecimal value) { + this.value = value; + } + + public String getModule() { + return module; + } + + public void setModule(String module) { + this.module = module; + } + + public int getSortOrder() { + return sortOrder; + } + + public void setSortOrder(int sortOrder) { + this.sortOrder = sortOrder; + } + + public Order getOrder() { + return order; + } + + public void setOrder(Order order) { + this.order = order; + } + + public void setOrderTotalCode(String orderTotalCode) { + this.orderTotalCode = orderTotalCode; + } + + public String getOrderTotalCode() { + return orderTotalCode; + } + + public void setOrderValueType(OrderValueType orderValueType) { + this.orderValueType = orderValueType; + } + + public OrderValueType getOrderValueType() { + return orderValueType; + } + + public void setOrderTotalType(OrderTotalType orderTotalType) { + this.orderTotalType = orderTotalType; + } + + public OrderTotalType getOrderTotalType() { + return orderTotalType; + } + + +} \ No newline at end of file diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotalItem.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotalItem.java new file mode 100755 index 0000000000..4b0f38de73 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotalItem.java @@ -0,0 +1,27 @@ +package com.salesmanager.core.model.order; + +import java.io.Serializable; +import java.math.BigDecimal; + +public class OrderTotalItem implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private BigDecimal itemPrice; + private String itemCode; + public void setItemPrice(BigDecimal itemPrice) { + this.itemPrice = itemPrice; + } + public BigDecimal getItemPrice() { + return itemPrice; + } + public void setItemCode(String itemCode) { + this.itemCode = itemCode; + } + public String getItemCode() { + return itemCode; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotalSummary.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotalSummary.java new file mode 100755 index 0000000000..f9e7191ea8 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotalSummary.java @@ -0,0 +1,56 @@ +package com.salesmanager.core.model.order; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + +/** + * Output object after total calculation + * @author Carl Samson + * + */ +public class OrderTotalSummary implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private BigDecimal subTotal;//one time price for items + private BigDecimal total;//final price + private BigDecimal taxTotal;//total of taxes + + private List totals;//all other fees (tax, shipping ....) + + public BigDecimal getSubTotal() { + return subTotal; + } + + public void setSubTotal(BigDecimal subTotal) { + this.subTotal = subTotal; + } + + public BigDecimal getTotal() { + return total; + } + + public void setTotal(BigDecimal total) { + this.total = total; + } + + public List getTotals() { + return totals; + } + + public void setTotals(List totals) { + this.totals = totals; + } + + public BigDecimal getTaxTotal() { + return taxTotal; + } + + public void setTaxTotal(BigDecimal taxTotal) { + this.taxTotal = taxTotal; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotalType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotalType.java new file mode 100755 index 0000000000..837c2cb438 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotalType.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.order; + +public enum OrderTotalType { + + SHIPPING, HANDLING, TAX, PRODUCT, SUBTOTAL, TOTAL, CREDIT, REFUND + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotalVariation.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotalVariation.java new file mode 100755 index 0000000000..90152b04d9 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderTotalVariation.java @@ -0,0 +1,23 @@ +package com.salesmanager.core.model.order; + +import java.util.List; + +/** + * Contains a list of negative OrderTotal variation + * that will be shown in the order summary + * @author carlsamson + * + */ +public abstract class OrderTotalVariation { + + List variations = null; + + public List getVariations() { + return variations; + } + + public void setVariations(List variations) { + this.variations = variations; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderType.java new file mode 100755 index 0000000000..1c31d073c0 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderType.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.order; + +public enum OrderType { + + ORDER, BOOKING + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderValueType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderValueType.java new file mode 100755 index 0000000000..bc1dc01b32 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/OrderValueType.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.order; + +public enum OrderValueType { + + ONE_TIME, MONTHLY + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/RebatesOrderTotalVariation.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/RebatesOrderTotalVariation.java new file mode 100755 index 0000000000..e162da8687 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/RebatesOrderTotalVariation.java @@ -0,0 +1,12 @@ +package com.salesmanager.core.model.order; + + +/** + * Implementation of rebates calculated used in the ordertotal calculation + * engine + * @author carlsamson + * + */ +public class RebatesOrderTotalVariation extends OrderTotalVariation { + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/attributes/OrderAttribute.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/attributes/OrderAttribute.java new file mode 100755 index 0000000000..467fe46611 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/attributes/OrderAttribute.java @@ -0,0 +1,81 @@ +package com.salesmanager.core.model.order.attributes; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.order.Order; + +/** + * Entity used for storing various attributes related to an Order + * @author c.samson + * + */ +@Entity +@Table (name="ORDER_ATTRIBUTE" ) +public class OrderAttribute extends SalesManagerEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "ORDER_ATTRIBUTE_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "ORDER_ATTR_ID_NEXT_VALUE") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Column (name ="IDENTIFIER", nullable=false) + private String key; + + @Column (name ="VALUE", nullable=false) + private String value; + + @ManyToOne(targetEntity = Order.class) + @JoinColumn(name = "ORDER_ID", nullable=false) + private Order order; + + public Order getOrder() { + return order; + } + + public void setOrder(Order order) { + this.order = order; + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/filehistory/FileHistory.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/filehistory/FileHistory.java new file mode 100755 index 0000000000..f5ea838f0b --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/filehistory/FileHistory.java @@ -0,0 +1,134 @@ +package com.salesmanager.core.model.order.filehistory; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.UniqueConstraint; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.utils.CloneUtils; + +@Entity +@Table (name="FILE_HISTORY", uniqueConstraints={ + @UniqueConstraint( + columnNames={ + "MERCHANT_ID", + "FILE_ID" + } + ) + } +) +public class FileHistory implements Serializable { + private static final long serialVersionUID = 1321251632883237664L; + + @Id + @Column(name = "FILE_HISTORY_ID", unique = true, nullable = false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", + pkColumnValue = "FILE_HISTORY_ID_NEXT_VALUE") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @ManyToOne(targetEntity = MerchantStore.class) + @JoinColumn(name = "MERCHANT_ID", nullable = false) + private MerchantStore store; + + @Column(name = "FILE_ID") + private Long fileId; + + @Column ( name="FILESIZE", nullable=false ) + private Integer filesize; + + @Temporal(TemporalType.TIMESTAMP ) + @Column ( name="DATE_ADDED", length=0, nullable=false ) + private Date dateAdded; + + @Temporal(TemporalType.TIMESTAMP) + @Column ( name="DATE_DELETED", length=0 ) + private Date dateDeleted; + + @Temporal(TemporalType.TIMESTAMP) + @Column ( name="ACCOUNTED_DATE", length=0 ) + private Date accountedDate; + + @Column ( name="DOWNLOAD_COUNT", nullable=false ) + private Integer downloadCount; + + public FileHistory() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public MerchantStore getStore() { + return store; + } + + public void setStore(MerchantStore store) { + this.store = store; + } + + public Long getFileId() { + return fileId; + } + + public void setFileId(Long fileId) { + this.fileId = fileId; + } + + public Integer getFilesize() { + return filesize; + } + + public void setFilesize(Integer filesize) { + this.filesize = filesize; + } + + public Date getDateAdded() { + return CloneUtils.clone(dateAdded); + } + + public void setDateAdded(Date dateAdded) { + this.dateAdded = CloneUtils.clone(dateAdded); + } + + public Date getDateDeleted() { + return CloneUtils.clone(dateDeleted); + } + + public void setDateDeleted(Date dateDeleted) { + this.dateDeleted = CloneUtils.clone(dateDeleted); + } + + public Date getAccountedDate() { + return CloneUtils.clone(accountedDate); + } + + public void setAccountedDate(Date accountedDate) { + this.accountedDate = CloneUtils.clone(accountedDate); + } + + public Integer getDownloadCount() { + return downloadCount; + } + + public void setDownloadCount(Integer downloadCount) { + this.downloadCount = downloadCount; + } + +} \ No newline at end of file diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderaccount/OrderAccount.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderaccount/OrderAccount.java new file mode 100755 index 0000000000..039ab42265 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderaccount/OrderAccount.java @@ -0,0 +1,106 @@ +package com.salesmanager.core.model.order.orderaccount; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.utils.CloneUtils; + +@Entity +@Table(name = "ORDER_ACCOUNT") +public class OrderAccount extends SalesManagerEntity { +private static final long serialVersionUID = -2429388347536330540L; + + @Id + @Column(name = "ORDER_ACCOUNT_ID", unique = true, nullable = false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "ORDER_ACCOUNT_ID_NEXT_VALUE") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @ManyToOne + @JoinColumn(name = "ORDER_ID", nullable = false) + private Order order; + + @Temporal(TemporalType.DATE) + @Column(name = "ORDER_ACCOUNT_START_DATE", nullable = false, length = 0) + private Date orderAccountStartDate; + + @Temporal(TemporalType.DATE) + @Column(name = "ORDER_ACCOUNT_END_DATE", length = 0) + private Date orderAccountEndDate; + + @Column(name = "ORDER_ACCOUNT_BILL_DAY", nullable = false) + private Integer orderAccountBillDay; + + @OneToMany(mappedBy = "orderAccount", cascade = CascadeType.ALL) + private Set orderAccountProducts = new HashSet(); + + public OrderAccount() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Order getOrder() { + return order; + } + + public void setOrder(Order order) { + this.order = order; + } + + public Date getOrderAccountStartDate() { + return CloneUtils.clone(orderAccountStartDate); + } + + public void setOrderAccountStartDate(Date orderAccountStartDate) { + this.orderAccountStartDate = CloneUtils.clone(orderAccountStartDate); + } + + public Date getOrderAccountEndDate() { + return CloneUtils.clone(orderAccountEndDate); + } + + public void setOrderAccountEndDate(Date orderAccountEndDate) { + this.orderAccountEndDate = CloneUtils.clone(orderAccountEndDate); + } + + public Integer getOrderAccountBillDay() { + return orderAccountBillDay; + } + + public void setOrderAccountBillDay(Integer orderAccountBillDay) { + this.orderAccountBillDay = orderAccountBillDay; + } + + public Set getOrderAccountProducts() { + return orderAccountProducts; + } + + public void setOrderAccountProducts( + Set orderAccountProducts) { + this.orderAccountProducts = orderAccountProducts; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderaccount/OrderAccountProduct.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderaccount/OrderAccountProduct.java new file mode 100755 index 0000000000..b9c789bf0a --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderaccount/OrderAccountProduct.java @@ -0,0 +1,166 @@ +package com.salesmanager.core.model.order.orderaccount; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.order.orderproduct.OrderProduct; +import com.salesmanager.core.utils.CloneUtils; + +@Entity +@Table (name="ORDER_ACCOUNT_PRODUCT" ) +public class OrderAccountProduct implements Serializable { + private static final long serialVersionUID = -7437197293537758668L; + + @Id + @Column (name="ORDER_ACCOUNT_PRODUCT_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", + pkColumnValue = "ORDERACCOUNTPRODUCT_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long orderAccountProductId; + + @ManyToOne + @JoinColumn(name = "ORDER_ACCOUNT_ID" , nullable=false) + private OrderAccount orderAccount; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "ORDER_PRODUCT_ID" , nullable=false) + private OrderProduct orderProduct; + + @Temporal(TemporalType.DATE) + @Column (name="ORDER_ACCOUNT_PRODUCT_ST_DT" , length=0 , nullable=false) + private Date orderAccountProductStartDate; + + @Temporal(TemporalType.DATE) + @Column (name="ORDER_ACCOUNT_PRODUCT_END_DT", length=0) + private Date orderAccountProductEndDate; + + @Temporal(TemporalType.TIMESTAMP) + @Column (name="ORDER_ACCOUNT_PRODUCT_EOT" , length=0 ) + private Date orderAccountProductEot; + + @Temporal(TemporalType.DATE) + @Column (name="ORDER_ACCOUNT_PRODUCT_ACCNT_DT" , length=0 ) + private Date orderAccountProductAccountedDate; + + @Temporal(TemporalType.TIMESTAMP) + @Column (name="ORDER_ACCOUNT_PRODUCT_L_ST_DT" , length=0 ) + private Date orderAccountProductLastStatusDate; + + @Column (name="ORDER_ACCOUNT_PRODUCT_L_TRX_ST" , nullable=false ) + private Integer orderAccountProductLastTransactionStatus; + + @Column (name="ORDER_ACCOUNT_PRODUCT_PM_FR_TY" , nullable=false ) + private Integer orderAccountProductPaymentFrequencyType; + + @Column (name="ORDER_ACCOUNT_PRODUCT_STATUS" , nullable=false ) + private Integer orderAccountProductStatus; + + public OrderAccountProduct() { + } + + public Long getOrderAccountProductId() { + return orderAccountProductId; + } + + public void setOrderAccountProductId(Long orderAccountProductId) { + this.orderAccountProductId = orderAccountProductId; + } + + public OrderAccount getOrderAccount() { + return orderAccount; + } + + public void setOrderAccount(OrderAccount orderAccount) { + this.orderAccount = orderAccount; + } + + public OrderProduct getOrderProduct() { + return orderProduct; + } + + public void setOrderProduct(OrderProduct orderProduct) { + this.orderProduct = orderProduct; + } + + public Date getOrderAccountProductStartDate() { + return CloneUtils.clone(orderAccountProductStartDate); + } + + public void setOrderAccountProductStartDate(Date orderAccountProductStartDate) { + this.orderAccountProductStartDate = CloneUtils.clone(orderAccountProductStartDate); + } + + public Date getOrderAccountProductEndDate() { + return CloneUtils.clone(orderAccountProductEndDate); + } + + public void setOrderAccountProductEndDate(Date orderAccountProductEndDate) { + this.orderAccountProductEndDate = CloneUtils.clone(orderAccountProductEndDate); + } + + public Date getOrderAccountProductEot() { + return CloneUtils.clone(orderAccountProductEot); + } + + public void setOrderAccountProductEot(Date orderAccountProductEot) { + this.orderAccountProductEot = CloneUtils.clone(orderAccountProductEot); + } + + public Date getOrderAccountProductAccountedDate() { + return CloneUtils.clone(orderAccountProductAccountedDate); + } + + public void setOrderAccountProductAccountedDate( + Date orderAccountProductAccountedDate) { + this.orderAccountProductAccountedDate = CloneUtils.clone(orderAccountProductAccountedDate); + } + + public Date getOrderAccountProductLastStatusDate() { + return CloneUtils.clone(orderAccountProductLastStatusDate); + } + + public void setOrderAccountProductLastStatusDate( + Date orderAccountProductLastStatusDate) { + this.orderAccountProductLastStatusDate = CloneUtils.clone(orderAccountProductLastStatusDate); + } + + public Integer getOrderAccountProductLastTransactionStatus() { + return orderAccountProductLastTransactionStatus; + } + + public void setOrderAccountProductLastTransactionStatus( + Integer orderAccountProductLastTransactionStatus) { + this.orderAccountProductLastTransactionStatus = orderAccountProductLastTransactionStatus; + } + + public Integer getOrderAccountProductPaymentFrequencyType() { + return orderAccountProductPaymentFrequencyType; + } + + public void setOrderAccountProductPaymentFrequencyType( + Integer orderAccountProductPaymentFrequencyType) { + this.orderAccountProductPaymentFrequencyType = orderAccountProductPaymentFrequencyType; + } + + public Integer getOrderAccountProductStatus() { + return orderAccountProductStatus; + } + + public void setOrderAccountProductStatus(Integer orderAccountProductStatus) { + this.orderAccountProductStatus = orderAccountProductStatus; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderproduct/OrderProduct.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderproduct/OrderProduct.java new file mode 100755 index 0000000000..59d9f52118 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderproduct/OrderProduct.java @@ -0,0 +1,140 @@ +package com.salesmanager.core.model.order.orderproduct; + +import java.math.BigDecimal; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.order.Order; + +@Entity +@Table (name="ORDER_PRODUCT" ) +public class OrderProduct extends SalesManagerEntity { + private static final long serialVersionUID = 1L; + + @Id + @Column (name="ORDER_PRODUCT_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "ORDER_PRODUCT_ID_NEXT_VALUE") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Column (name="PRODUCT_SKU") + private String sku; + + @Column (name="PRODUCT_NAME" , length=64 , nullable=false) + private String productName; + + @Column (name="PRODUCT_QUANTITY") + private int productQuantity; + + @Column (name="ONETIME_CHARGE" , nullable=false ) + private BigDecimal oneTimeCharge; + + @JsonIgnore + @ManyToOne(targetEntity = Order.class) + @JoinColumn(name = "ORDER_ID", nullable = false) + private Order order; + + @OneToMany(mappedBy = "orderProduct", cascade = CascadeType.ALL) + private Set orderAttributes = new HashSet(); + + @OneToMany(mappedBy = "orderProduct", cascade = CascadeType.ALL) + private Set prices = new HashSet(); + + @OneToMany(mappedBy = "orderProduct", cascade = CascadeType.ALL) + private Set downloads = new HashSet(); + + public OrderProduct() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + + public String getProductName() { + return productName; + } + + public void setProductName(String productName) { + this.productName = productName; + } + + public int getProductQuantity() { + return productQuantity; + } + + public void setProductQuantity(int productQuantity) { + this.productQuantity = productQuantity; + } + + + + public Order getOrder() { + return order; + } + + public void setOrder(Order order) { + this.order = order; + } + + + public Set getOrderAttributes() { + return orderAttributes; + } + + public void setOrderAttributes(Set orderAttributes) { + this.orderAttributes = orderAttributes; + } + + public Set getPrices() { + return prices; + } + + public void setPrices(Set prices) { + this.prices = prices; + } + + public Set getDownloads() { + return downloads; + } + + public void setDownloads(Set downloads) { + this.downloads = downloads; + } + + + public void setSku(String sku) { + this.sku = sku; + } + + public String getSku() { + return sku; + } + + public void setOneTimeCharge(BigDecimal oneTimeCharge) { + this.oneTimeCharge = oneTimeCharge; + } + + public BigDecimal getOneTimeCharge() { + return oneTimeCharge; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderproduct/OrderProductAttribute.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderproduct/OrderProductAttribute.java new file mode 100755 index 0000000000..8b5a607fe8 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderproduct/OrderProductAttribute.java @@ -0,0 +1,134 @@ +package com.salesmanager.core.model.order.orderproduct; + +import java.io.Serializable; +import java.math.BigDecimal; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; + +@Entity +@Table (name="ORDER_PRODUCT_ATTRIBUTE" ) +public class OrderProductAttribute implements Serializable { + private static final long serialVersionUID = 6037571119918073015L; + + @Id + @Column (name="ORDER_PRODUCT_ATTRIBUTE_ID", nullable=false , unique=true ) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "ORDER_PRODUCT_ATTR_ID_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Column ( name= "PRODUCT_ATTRIBUTE_PRICE" , nullable=false , precision=15 , scale=4 ) + private BigDecimal productAttributePrice; + + @Column ( name= "PRODUCT_ATTRIBUTE_IS_FREE" , nullable=false ) + private boolean productAttributeIsFree; + + @Column ( name= "PRODUCT_ATTRIBUTE_WEIGHT" , precision=15 , scale=4 ) + private java.math.BigDecimal productAttributeWeight; + + @JsonIgnore + @ManyToOne + @JoinColumn(name = "ORDER_PRODUCT_ID", nullable = false) + private OrderProduct orderProduct; + + @Column(name = "PRODUCT_OPTION_ID", nullable = false) + private Long productOptionId; + + + @Column(name = "PRODUCT_OPTION_VALUE_ID", nullable = false) + private Long productOptionValueId; + + @Column ( name= "PRODUCT_ATTRIBUTE_NAME") + private String productAttributeName; + + @Column ( name= "PRODUCT_ATTRIBUTE_VAL_NAME") + private String productAttributeValueName; + + public OrderProductAttribute() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + + public boolean isProductAttributeIsFree() { + return productAttributeIsFree; + } + + public void setProductAttributeIsFree(boolean productAttributeIsFree) { + this.productAttributeIsFree = productAttributeIsFree; + } + + public java.math.BigDecimal getProductAttributeWeight() { + return productAttributeWeight; + } + + public void setProductAttributeWeight( + java.math.BigDecimal productAttributeWeight) { + this.productAttributeWeight = productAttributeWeight; + } + + public OrderProduct getOrderProduct() { + return orderProduct; + } + + public void setOrderProduct(OrderProduct orderProduct) { + this.orderProduct = orderProduct; + } + + public String getProductAttributeName() { + return productAttributeName; + } + + public void setProductAttributeName(String productAttributeName) { + this.productAttributeName = productAttributeName; + } + + public String getProductAttributeValueName() { + return productAttributeValueName; + } + + public void setProductAttributeValueName(String productAttributeValueName) { + this.productAttributeValueName = productAttributeValueName; + } + + public BigDecimal getProductAttributePrice() { + return productAttributePrice; + } + + public void setProductAttributePrice(BigDecimal productAttributePrice) { + this.productAttributePrice = productAttributePrice; + } + + public Long getProductOptionId() { + return productOptionId; + } + + public void setProductOptionId(Long productOptionId) { + this.productOptionId = productOptionId; + } + + public Long getProductOptionValueId() { + return productOptionValueId; + } + + public void setProductOptionValueId(Long productOptionValueId) { + this.productOptionValueId = productOptionValueId; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderproduct/OrderProductDownload.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderproduct/OrderProductDownload.java new file mode 100755 index 0000000000..daf94955eb --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderproduct/OrderProductDownload.java @@ -0,0 +1,92 @@ +package com.salesmanager.core.model.order.orderproduct; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.generic.SalesManagerEntity; + +@Entity +@Table (name="ORDER_PRODUCT_DOWNLOAD") +public class OrderProductDownload extends SalesManagerEntity implements Serializable { + private static final long serialVersionUID = -8935511990745477240L; + + public final static int DEFAULT_DOWNLOAD_MAX_DAYS = 31; + + @Id + @Column (name="ORDER_PRODUCT_DOWNLOAD_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "ORDER_PRODUCT_DL_ID_NEXT_VALUE") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @JsonIgnore + @ManyToOne + @JoinColumn(name = "ORDER_PRODUCT_ID", nullable = false) + private OrderProduct orderProduct; + + @Column(name = "ORDER_PRODUCT_FILENAME", nullable = false) + private String orderProductFilename; + + @Column(name = "DOWNLOAD_MAXDAYS", nullable = false) + private Integer maxdays = DEFAULT_DOWNLOAD_MAX_DAYS; + + @Column(name = "DOWNLOAD_COUNT", nullable = false) + private Integer downloadCount; + + + + public OrderProductDownload() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public OrderProduct getOrderProduct() { + return orderProduct; + } + + public void setOrderProduct(OrderProduct orderProduct) { + this.orderProduct = orderProduct; + } + + public String getOrderProductFilename() { + return orderProductFilename; + } + + public void setOrderProductFilename(String orderProductFilename) { + this.orderProductFilename = orderProductFilename; + } + + public Integer getMaxdays() { + return maxdays; + } + + public void setMaxdays(Integer maxdays) { + this.maxdays = maxdays; + } + + public Integer getDownloadCount() { + return downloadCount; + } + + public void setDownloadCount(Integer downloadCount) { + this.downloadCount = downloadCount; + } + + +} \ No newline at end of file diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderproduct/OrderProductPrice.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderproduct/OrderProductPrice.java new file mode 100755 index 0000000000..1d02d67be3 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderproduct/OrderProductPrice.java @@ -0,0 +1,140 @@ +package com.salesmanager.core.model.order.orderproduct; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; + +@Entity +@Table (name="ORDER_PRODUCT_PRICE" ) +public class OrderProductPrice implements Serializable { + private static final long serialVersionUID = 3734737890163564311L; + + @Id + @Column (name="ORDER_PRODUCT_PRICE_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", + pkColumnValue = "ORDER_PRD_PRICE_ID_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @JsonIgnore + @ManyToOne + @JoinColumn(name = "ORDER_PRODUCT_ID", nullable = false) + private OrderProduct orderProduct; + + + @Column(name = "PRODUCT_PRICE_CODE", nullable = false , length=64 ) + private String productPriceCode; + + @Column(name = "PRODUCT_PRICE", nullable = false) + private BigDecimal productPrice; + + @Column(name = "PRODUCT_PRICE_SPECIAL") + private BigDecimal productPriceSpecial; + + @Temporal(TemporalType.TIMESTAMP) + @Column (name="PRD_PRICE_SPECIAL_ST_DT" , length=0) + private Date productPriceSpecialStartDate; + + @Temporal(TemporalType.TIMESTAMP) + @Column (name="PRD_PRICE_SPECIAL_END_DT" , length=0) + private Date productPriceSpecialEndDate; + + + @Column(name = "DEFAULT_PRICE", nullable = false) + private Boolean defaultPrice; + + + @Column(name = "PRODUCT_PRICE_NAME", nullable = true) + private String productPriceName; + + public OrderProductPrice() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Boolean getDefaultPrice() { + return defaultPrice; + } + + public void setDefaultPrice(Boolean defaultPrice) { + this.defaultPrice = defaultPrice; + } + + public String getProductPriceName() { + return productPriceName; + } + + public void setProductPriceName(String productPriceName) { + this.productPriceName = productPriceName; + } + + public OrderProduct getOrderProduct() { + return orderProduct; + } + + public void setOrderProduct(OrderProduct orderProduct) { + this.orderProduct = orderProduct; + } + + public void setProductPriceCode(String productPriceCode) { + this.productPriceCode = productPriceCode; + } + + public String getProductPriceCode() { + return productPriceCode; + } + + public void setProductPriceSpecialStartDate( + Date productPriceSpecialStartDate) { + this.productPriceSpecialStartDate = productPriceSpecialStartDate; + } + + public Date getProductPriceSpecialStartDate() { + return productPriceSpecialStartDate; + } + + public void setProductPriceSpecialEndDate(Date productPriceSpecialEndDate) { + this.productPriceSpecialEndDate = productPriceSpecialEndDate; + } + + public Date getProductPriceSpecialEndDate() { + return productPriceSpecialEndDate; + } + + public void setProductPriceSpecial(BigDecimal productPriceSpecial) { + this.productPriceSpecial = productPriceSpecial; + } + + public BigDecimal getProductPriceSpecial() { + return productPriceSpecial; + } + + public void setProductPrice(BigDecimal productPrice) { + this.productPrice = productPrice; + } + + public BigDecimal getProductPrice() { + return productPrice; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderstatus/OrderStatus.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderstatus/OrderStatus.java new file mode 100755 index 0000000000..93e9dbe36a --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderstatus/OrderStatus.java @@ -0,0 +1,21 @@ +package com.salesmanager.core.model.order.orderstatus; + +public enum OrderStatus { + + ORDERED("ordered"), + PROCESSED("processed"), + DELIVERED("delivered"), + REFUNDED("refunded"), + CANCELED("canceled"), + ; + + private String value; + + private OrderStatus(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderstatus/OrderStatusHistory.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderstatus/OrderStatusHistory.java new file mode 100755 index 0000000000..cd072a128d --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/orderstatus/OrderStatusHistory.java @@ -0,0 +1,109 @@ +package com.salesmanager.core.model.order.orderstatus; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.hibernate.annotations.Type; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.utils.CloneUtils; + +@Entity +@Table (name="ORDER_STATUS_HISTORY" ) +public class OrderStatusHistory implements Serializable { + private static final long serialVersionUID = 3438730310126102187L; + + @Id + @Column ( name="ORDER_STATUS_HISTORY_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", + pkColumnValue = "STATUS_HIST_ID_NEXT_VALUE") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @JsonIgnore + @ManyToOne(targetEntity = Order.class) + @JoinColumn(name = "ORDER_ID", nullable = false) + private Order order; + + @Enumerated(value = EnumType.STRING) + private OrderStatus status; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "DATE_ADDED", nullable = false) + private Date dateAdded; + + @Column(name = "CUSTOMER_NOTIFIED") + private java.lang.Integer customerNotified; + + @Column(name = "COMMENTS") + @Type(type = "org.hibernate.type.TextType") + private String comments; + + public OrderStatusHistory() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Order getOrder() { + return order; + } + + public void setOrder(Order order) { + this.order = order; + } + + public OrderStatus getStatus() { + return status; + } + + public void setStatus(OrderStatus status) { + this.status = status; + } + + public Date getDateAdded() { + return CloneUtils.clone(dateAdded); + } + + public void setDateAdded(Date dateAdded) { + this.dateAdded = CloneUtils.clone(dateAdded); + } + + public java.lang.Integer getCustomerNotified() { + return customerNotified; + } + + public void setCustomerNotified(java.lang.Integer customerNotified) { + this.customerNotified = customerNotified; + } + + public String getComments() { + return comments; + } + + public void setComments(String comments) { + this.comments = comments; + } + +} \ No newline at end of file diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/order/payment/CreditCard.java b/sm-core-model/src/main/java/com/salesmanager/core/model/order/payment/CreditCard.java new file mode 100755 index 0000000000..2afa15a346 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/order/payment/CreditCard.java @@ -0,0 +1,69 @@ +package com.salesmanager.core.model.order.payment; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; + +import com.salesmanager.core.model.payments.CreditCardType; + +@Embeddable +public class CreditCard { + + @Column (name ="CARD_TYPE") + @Enumerated(value = EnumType.STRING) + private CreditCardType cardType; + + @Column (name ="CC_OWNER") + private String ccOwner; + + @Column (name ="CC_NUMBER") + private String ccNumber; + + @Column (name ="CC_EXPIRES") + private String ccExpires; + + @Column (name ="CC_CVV") + private String ccCvv; + + public String getCcOwner() { + return ccOwner; + } + + public void setCcOwner(String ccOwner) { + this.ccOwner = ccOwner; + } + + public String getCcNumber() { + return ccNumber; + } + + public void setCcNumber(String ccNumber) { + this.ccNumber = ccNumber; + } + + public String getCcExpires() { + return ccExpires; + } + + public void setCcExpires(String ccExpires) { + this.ccExpires = ccExpires; + } + + public String getCcCvv() { + return ccCvv; + } + + public void setCcCvv(String ccCvv) { + this.ccCvv = ccCvv; + } + + public void setCardType(CreditCardType cardType) { + this.cardType = cardType; + } + + public CreditCardType getCardType() { + return cardType; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/payments/BasicPayment.java b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/BasicPayment.java new file mode 100755 index 0000000000..8cf976999c --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/BasicPayment.java @@ -0,0 +1,11 @@ +package com.salesmanager.core.model.payments; + + +/** + * When the user performs a payment using money order or cheque + * @author Carl Samson + * + */ +public class BasicPayment extends Payment { + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/payments/CreditCardPayment.java b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/CreditCardPayment.java new file mode 100755 index 0000000000..dc3163ad13 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/CreditCardPayment.java @@ -0,0 +1,53 @@ +package com.salesmanager.core.model.payments; + +/** + * When the user performs a payment using a credit card + * @author Carl Samson + * + */ +public class CreditCardPayment extends Payment { + + private String creditCardNumber; + private String credidCardValidationNumber; + private String expirationMonth; + private String expirationYear; + private String cardOwner; + private CreditCardType creditCard; + public String getCreditCardNumber() { + return creditCardNumber; + } + public void setCreditCardNumber(String creditCardNumber) { + this.creditCardNumber = creditCardNumber; + } + public String getCredidCardValidationNumber() { + return credidCardValidationNumber; + } + public void setCredidCardValidationNumber(String credidCardValidationNumber) { + this.credidCardValidationNumber = credidCardValidationNumber; + } + public String getExpirationMonth() { + return expirationMonth; + } + public void setExpirationMonth(String expirationMonth) { + this.expirationMonth = expirationMonth; + } + public String getExpirationYear() { + return expirationYear; + } + public void setExpirationYear(String expirationYear) { + this.expirationYear = expirationYear; + } + public String getCardOwner() { + return cardOwner; + } + public void setCardOwner(String cardOwner) { + this.cardOwner = cardOwner; + } + public CreditCardType getCreditCard() { + return creditCard; + } + public void setCreditCard(CreditCardType creditCard) { + this.creditCard = creditCard; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/payments/CreditCardType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/CreditCardType.java new file mode 100755 index 0000000000..b30f3c918f --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/CreditCardType.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.payments; + +public enum CreditCardType { + + AMEX, VISA, MASTERCARD, DINERS, DISCOVERY + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/payments/Payment.java b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/Payment.java new file mode 100755 index 0000000000..0ef1f7e53b --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/Payment.java @@ -0,0 +1,65 @@ +package com.salesmanager.core.model.payments; + +import java.math.BigDecimal; +import java.util.Map; + +import com.salesmanager.core.model.reference.currency.Currency; + +public class Payment { + + private PaymentType paymentType; + private TransactionType transactionType = TransactionType.AUTHORIZECAPTURE; + private String moduleName; + private Currency currency; + private BigDecimal amount; + private Map paymentMetaData = null; + + public void setPaymentType(PaymentType paymentType) { + this.paymentType = paymentType; + } + + public PaymentType getPaymentType() { + return paymentType; + } + + public void setTransactionType(TransactionType transactionType) { + this.transactionType = transactionType; + } + + public TransactionType getTransactionType() { + return transactionType; + } + + public void setModuleName(String moduleName) { + this.moduleName = moduleName; + } + + public String getModuleName() { + return moduleName; + } + + public Currency getCurrency() { + return currency; + } + + public void setCurrency(Currency currency) { + this.currency = currency; + } + + public Map getPaymentMetaData() { + return paymentMetaData; + } + + public void setPaymentMetaData(Map paymentMetaData) { + this.paymentMetaData = paymentMetaData; + } + + public BigDecimal getAmount() { + return amount; + } + + public void setAmount(BigDecimal amount) { + this.amount = amount; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/payments/PaymentMethod.java b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/PaymentMethod.java new file mode 100755 index 0000000000..d1889903a4 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/PaymentMethod.java @@ -0,0 +1,57 @@ +package com.salesmanager.core.model.payments; + +import java.io.Serializable; + +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; + +/** + * Object to be used in store front with meta data and configuration + * informations required to display to the end user + * @author Carl Samson + * + */ +public class PaymentMethod implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String paymentMethodCode; + private PaymentType paymentType; + private boolean defaultSelected; + private IntegrationModule module; + private IntegrationConfiguration informations; + + public PaymentType getPaymentType() { + return paymentType; + } + public void setPaymentType(PaymentType paymentType) { + this.paymentType = paymentType; + } + public String getPaymentMethodCode() { + return paymentMethodCode; + } + public void setPaymentMethodCode(String paymentMethodCode) { + this.paymentMethodCode = paymentMethodCode; + } + public boolean isDefaultSelected() { + return defaultSelected; + } + public void setDefaultSelected(boolean defaultSelected) { + this.defaultSelected = defaultSelected; + } + public IntegrationModule getModule() { + return module; + } + public void setModule(IntegrationModule module) { + this.module = module; + } + public IntegrationConfiguration getInformations() { + return informations; + } + public void setInformations(IntegrationConfiguration informations) { + this.informations = informations; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/payments/PaymentType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/PaymentType.java new file mode 100755 index 0000000000..70b2577e9d --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/PaymentType.java @@ -0,0 +1,28 @@ +package com.salesmanager.core.model.payments; + +public enum PaymentType { + + + + CREDITCARD("creditcard"), FREE("free"), COD("cod"), MONEYORDER("moneyorder"), PAYPAL("paypal"), + INVOICE("invoice"), DIRECTBANK("directbank"), PAYMENTPLAN("paymentplan"), ACCOUNTCREDIT("accountcredit"); + + + private String paymentType; + + PaymentType(String type) { + paymentType = type; + } + + public static PaymentType fromString(String text) { + if (text != null) { + for (PaymentType b : PaymentType.values()) { + String payemntType = text.toUpperCase(); + if (payemntType.equalsIgnoreCase(b.name())) { + return b; + } + } + } + return null; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/payments/PaypalPayment.java b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/PaypalPayment.java new file mode 100755 index 0000000000..bba680455c --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/PaypalPayment.java @@ -0,0 +1,31 @@ +package com.salesmanager.core.model.payments; + +/** + * When the user performs a payment using paypal + * @author Carl Samson + * + */ +public class PaypalPayment extends Payment { + + //express checkout + private String payerId; + private String paymentToken; + + public PaypalPayment() { + super.setPaymentType(PaymentType.PAYPAL); + } + + public void setPayerId(String payerId) { + this.payerId = payerId; + } + public String getPayerId() { + return payerId; + } + public void setPaymentToken(String paymentToken) { + this.paymentToken = paymentToken; + } + public String getPaymentToken() { + return paymentToken; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/payments/Transaction.java b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/Transaction.java new file mode 100755 index 0000000000..4915a6302e --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/Transaction.java @@ -0,0 +1,187 @@ +package com.salesmanager.core.model.payments; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Transient; + +import org.hibernate.annotations.Type; +import org.json.simple.JSONAware; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.order.Order; + + +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "SM_TRANSACTION") +public class Transaction extends SalesManagerEntity implements Serializable, Auditable, JSONAware { + + + private static final Logger LOGGER = LoggerFactory.getLogger(Transaction.class); + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "TRANSACTION_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "TRANSACT_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="ORDER_ID", nullable=true) + private Order order; + + @Column(name="AMOUNT") + private BigDecimal amount; + + @Column(name="TRANSACTION_DATE") + @Temporal(TemporalType.TIMESTAMP) + private Date transactionDate; + + @Column(name="TRANSACTION_TYPE") + @Enumerated(value = EnumType.STRING) + private TransactionType transactionType; + + @Column(name="PAYMENT_TYPE") + @Enumerated(value = EnumType.STRING) + private PaymentType paymentType; + + @Column(name="DETAILS") + @Type(type = "org.hibernate.type.TextType") + private String details; + + @Transient + private Map transactionDetails= new HashMap(); + + @Override + public AuditSection getAuditSection() { + return this.auditSection; + } + + @Override + public void setAuditSection(AuditSection audit) { + this.auditSection = audit; + + } + + @Override + public Long getId() { + return this.id; + } + + @Override + public void setId(Long id) { + this.id = id; + + } + + public Order getOrder() { + return order; + } + + public void setOrder(Order order) { + this.order = order; + } + + public BigDecimal getAmount() { + return amount; + } + + public void setAmount(BigDecimal amount) { + this.amount = amount; + } + + public Date getTransactionDate() { + return transactionDate; + } + + public void setTransactionDate(Date transactionDate) { + this.transactionDate = transactionDate; + } + + public TransactionType getTransactionType() { + return transactionType; + } + + public String getTransactionTypeName() { + return this.getTransactionType()!=null?this.getTransactionType().name():""; + } + + public void setTransactionType(TransactionType transactionType) { + this.transactionType = transactionType; + } + + public PaymentType getPaymentType() { + return paymentType; + } + + public void setPaymentType(PaymentType paymentType) { + this.paymentType = paymentType; + } + + public String getDetails() { + return details; + } + + public void setDetails(String details) { + this.details = details; + } + + public Map getTransactionDetails() { + return transactionDetails; + } + + public void setTransactionDetails(Map transactionDetails) { + this.transactionDetails = transactionDetails; + } + + @Override + public String toJSONString() { + + if(this.getTransactionDetails()!=null && this.getTransactionDetails().size()>0) { + ObjectMapper mapper = new ObjectMapper(); + try { + return mapper.writeValueAsString(this.getTransactionDetails()); + } catch (Exception e) { + LOGGER.error("Cannot parse transactions map",e); + } + + } + + return null; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/payments/TransactionType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/TransactionType.java new file mode 100755 index 0000000000..ff3f18edf2 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/payments/TransactionType.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.payments; + +public enum TransactionType { + + INIT, AUTHORIZE, CAPTURE, AUTHORIZECAPTURE, REFUND, OK + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/reference/country/Country.java b/sm-core-model/src/main/java/com/salesmanager/core/model/reference/country/Country.java new file mode 100755 index 0000000000..62203df196 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/reference/country/Country.java @@ -0,0 +1,129 @@ +package com.salesmanager.core.model.reference.country; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.Cacheable; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Transient; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.reference.geozone.GeoZone; +import com.salesmanager.core.model.reference.zone.Zone; + +@Entity +@Table(name = "COUNTRY") +@Cacheable +public class Country extends SalesManagerEntity { + private static final long serialVersionUID = 1L; + + @Id + @Column(name="COUNTRY_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", + pkColumnValue = "COUNTRY_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Integer id; + + @JsonIgnore + @OneToMany(mappedBy = "country", cascade = CascadeType.ALL) + private Set descriptions = new HashSet(); + + @JsonIgnore + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "country") + private Set zones = new HashSet(); + + @ManyToOne(targetEntity = GeoZone.class) + @JoinColumn(name = "GEOZONE_ID") + private GeoZone geoZone; + + @Column(name = "COUNTRY_SUPPORTED") + private boolean supported = true; + + @Column(name = "COUNTRY_ISOCODE", unique=true, nullable = false) + private String isoCode; + + @Transient + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Country() { + } + + public Country(String isoCode) { + this.setIsoCode(isoCode); + } + + public boolean getSupported() { + return supported; + } + + public void setSupported(boolean supported) { + this.supported = supported; + } + + public String getIsoCode() { + return isoCode; + } + + public void setIsoCode(String isoCode) { + this.isoCode = isoCode; + } + + + @Override + public Integer getId() { + return id; + } + + @Override + public void setId(Integer id) { + this.id = id; + } + + + public Set getZones() { + return zones; + } + + public void setZones(Set zones) { + this.zones = zones; + } + + + public GeoZone getGeoZone() { + return geoZone; + } + + public void setGeoZone(GeoZone geoZone) { + this.geoZone = geoZone; + } + + + public Set getDescriptions() { + return descriptions; + } + + public void setDescriptions(Set descriptions) { + this.descriptions = descriptions; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/reference/country/CountryDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/reference/country/CountryDescription.java new file mode 100755 index 0000000000..11513b8feb --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/reference/country/CountryDescription.java @@ -0,0 +1,50 @@ +package com.salesmanager.core.model.reference.country; + +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.description.Description; +import com.salesmanager.core.model.reference.language.Language; + +@Entity +@Table(name = "COUNTRY_DESCRIPTION", uniqueConstraints={ + @UniqueConstraint(columnNames={ + "COUNTRY_ID", + "LANGUAGE_ID" + }) + } +) +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "country_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +//@SequenceGenerator(name = "description_gen", sequenceName = "country_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_SEQUENCE_START) +public class CountryDescription extends Description { + private static final long serialVersionUID = 1L; + + @JsonIgnore + @ManyToOne(targetEntity = Country.class) + @JoinColumn(name = "COUNTRY_ID", nullable = false) + private Country country; + + public CountryDescription() { + } + + public CountryDescription(Language language, String name) { + this.setLanguage(language); + this.setName(name); + } + + public Country getCountry() { + return country; + } + + public void setCountry(Country country) { + this.country = country; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/reference/currency/Currency.java b/sm-core-model/src/main/java/com/salesmanager/core/model/reference/currency/Currency.java new file mode 100755 index 0000000000..fa058813b2 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/reference/currency/Currency.java @@ -0,0 +1,90 @@ +package com.salesmanager.core.model.reference.currency; + +import java.io.Serializable; + +import javax.persistence.Cacheable; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.generic.SalesManagerEntity; + +@Entity +@Table(name = "CURRENCY") +@Cacheable +public class Currency extends SalesManagerEntity implements Serializable { + private static final long serialVersionUID = -999926410367685145L; + + @Id + @Column(name = "CURRENCY_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "CURRENCY_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Column(name = "CURRENCY_CURRENCY_CODE" ,nullable = false, unique = true) + private java.util.Currency currency; + + @Column(name = "CURRENCY_SUPPORTED") + private Boolean supported = true; + + @Column(name = "CURRENCY_CODE", unique = true) + private String code; + + @Column(name = "CURRENCY_NAME", unique = true) + private String name; + + public Currency() { + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public java.util.Currency getCurrency() { + return currency; + } + + public void setCurrency(java.util.Currency currency) { + this.currency = currency; + this.code = currency.getCurrencyCode(); + } + + public Boolean getSupported() { + return supported; + } + + public void setSupported(Boolean supported) { + this.supported = supported; + } + + public String getCode() { + if (currency.getCurrencyCode() != code) { + return currency.getCurrencyCode(); + } + return code; + } + + public String getSymbol() { + return currency.getSymbol(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/reference/geozone/GeoZone.java b/sm-core-model/src/main/java/com/salesmanager/core/model/reference/geozone/GeoZone.java new file mode 100755 index 0000000000..777361969b --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/reference/geozone/GeoZone.java @@ -0,0 +1,95 @@ +package com.salesmanager.core.model.reference.geozone; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.reference.country.Country; + +@Entity +@Table(name = "GEOZONE") +// TODO : create DAO / Service +public class GeoZone extends SalesManagerEntity { + private static final long serialVersionUID = -5992008645857938825L; + + @Id + @Column(name = "GEOZONE_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "GEOZONE_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @OneToMany(mappedBy = "geoZone", cascade = CascadeType.ALL) + private List descriptions = new ArrayList(); + + @JsonIgnore + @OneToMany(mappedBy = "geoZone", targetEntity = Country.class) + private List countries = new ArrayList(); + + + + @Column(name = "GEOZONE_NAME") + private String name; + + @Column(name = "GEOZONE_CODE") + private String code; + + public GeoZone() { + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public List getCountries() { + return countries; + } + + public void setCountries(List countries) { + this.countries = countries; + } + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/reference/geozone/GeoZoneDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/reference/geozone/GeoZoneDescription.java new file mode 100755 index 0000000000..41c04f045c --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/reference/geozone/GeoZoneDescription.java @@ -0,0 +1,42 @@ +package com.salesmanager.core.model.reference.geozone; + +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.description.Description; + +@Entity +@Table(name="GEOZONE_DESCRIPTION", uniqueConstraints={ + @UniqueConstraint(columnNames={ + "GEOZONE_ID", + "LANGUAGE_ID" + }) + } +) + +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "geozone_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +//@SequenceGenerator(name = "description_gen", sequenceName = "geozone_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_SEQUENCE_START) +public class GeoZoneDescription extends Description { + private static final long serialVersionUID = 1L; + + @ManyToOne(targetEntity = GeoZone.class) + @JoinColumn(name = "GEOZONE_ID") + private GeoZone geoZone; + + public GeoZoneDescription() { + } + + public GeoZone getGeoZone() { + return geoZone; + } + + public void setGeoZone(GeoZone geoZone) { + this.geoZone = geoZone; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/reference/language/Language.java b/sm-core-model/src/main/java/com/salesmanager/core/model/reference/language/Language.java new file mode 100755 index 0000000000..0f15b5411c --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/reference/language/Language.java @@ -0,0 +1,117 @@ +package com.salesmanager.core.model.reference.language; + +import java.util.ArrayList; +import java.util.List; +import javax.persistence.Cacheable; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.ManyToMany; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "LANGUAGE", indexes = { @Index(name="CODE_IDX2", columnList = "CODE")}) +@Cacheable +public class Language extends SalesManagerEntity implements Auditable { + private static final long serialVersionUID = 1L; + + + + @Id + @Column(name = "LANGUAGE_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", + valueColumnName = "SEQ_COUNT", pkColumnValue = "LANG_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Integer id; + + @JsonIgnore + @Embedded + private AuditSection auditSection = new AuditSection(); + + @Column(name = "CODE", nullable = false) + private String code; + + @JsonIgnore + @Column(name = "SORT_ORDER") + private Integer sortOrder; + + @JsonIgnore + @OneToMany(mappedBy = "defaultLanguage", targetEntity = MerchantStore.class) + private List storesDefaultLanguage; + + @JsonIgnore + @ManyToMany(mappedBy = "languages", targetEntity = MerchantStore.class, fetch = FetchType.LAZY) + private List stores = new ArrayList(); + + public Language() {} + + public Language(String code) { + this.setCode(code); + } + + @Override + public Integer getId() { + return id; + } + + @Override + public void setId(Integer id) { + this.id = id; + } + + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public Integer getSortOrder() { + return sortOrder; + } + + public void setSortOrder(Integer sortOrder) { + this.sortOrder = sortOrder; + } + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection auditSection) { + this.auditSection = auditSection; + } + + @Override + public boolean equals(Object obj) { + if (null == obj) + return false; + if (!(obj instanceof Language)) { + return false; + } else { + Language language = (Language) obj; + return (this.id == language.getId()); + } + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/reference/zone/Zone.java b/sm-core-model/src/main/java/com/salesmanager/core/model/reference/zone/Zone.java new file mode 100755 index 0000000000..32558dc490 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/reference/zone/Zone.java @@ -0,0 +1,105 @@ +package com.salesmanager.core.model.reference.zone; + +import java.util.ArrayList; +import java.util.List; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Transient; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.reference.country.Country; + +@Entity +@Table(name = "ZONE") +public class Zone extends SalesManagerEntity { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "ZONE_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", + valueColumnName = "SEQ_COUNT", pkColumnValue = "ZONE_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @JsonIgnore + @OneToMany(mappedBy = "zone", cascade = CascadeType.ALL) + private List descriptions = new ArrayList(); + + @JsonIgnore + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "COUNTRY_ID", nullable = false) + private Country country; + + @Transient + private String name; + + + + @Column(name = "ZONE_CODE", unique = true, nullable = false) + private String code; + + public Zone() {} + + public Zone(Country country, String name, String code) { + this.setCode(code); + this.setCountry(country); + this.setCode(name); + } + + public Country getCountry() { + return country; + } + + public void setCountry(Country country) { + this.country = country; + } + + + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptons(List descriptions) { + this.descriptions = descriptions; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/reference/zone/ZoneDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/reference/zone/ZoneDescription.java new file mode 100755 index 0000000000..df177780ef --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/reference/zone/ZoneDescription.java @@ -0,0 +1,49 @@ +package com.salesmanager.core.model.reference.zone; + +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.description.Description; +import com.salesmanager.core.model.reference.language.Language; + +@Entity +@Table(name="ZONE_DESCRIPTION", uniqueConstraints={ + @UniqueConstraint(columnNames={ + "ZONE_ID", + "LANGUAGE_ID" + }) + } +) +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "zone_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +//@SequenceGenerator(name = "description_gen", sequenceName = "zone_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_SEQUENCE_START) +public class ZoneDescription extends Description { + private static final long serialVersionUID = 1L; + + @JsonIgnore + @ManyToOne(targetEntity = Zone.class) + @JoinColumn(name = "ZONE_ID", nullable = false) + private Zone zone; + + public ZoneDescription() { + } + + public ZoneDescription(Zone zone, Language language, String name) { + setZone(zone); + setLanguage(language); + setName(name); + } + + public Zone getZone() { + return zone; + } + + public void setZone(Zone zone) { + this.zone = zone; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/security/Secrets.java b/sm-core-model/src/main/java/com/salesmanager/core/model/security/Secrets.java new file mode 100755 index 0000000000..9ffd6806e6 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/security/Secrets.java @@ -0,0 +1,26 @@ +package com.salesmanager.core.model.security; + +import java.io.Serializable; + +public class Secrets implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String userName; + private String password; + public String getUserName() { + return userName; + } + public void setUserName(String userName) { + this.userName = userName; + } + public String getPassword() { + return password; + } + public void setPassword(String password) { + this.password = password; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/Package.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/Package.java new file mode 100644 index 0000000000..cdf710b223 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/Package.java @@ -0,0 +1,80 @@ +package com.salesmanager.core.model.shipping; + +import java.io.Serializable; + +public class Package implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * + */ + public int getTreshold() { + return treshold; + } + public void setTreshold(int treshold) { + this.treshold = treshold; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public double getBoxWidth() { + return boxWidth; + } + public void setBoxWidth(double boxWidth) { + this.boxWidth = boxWidth; + } + public double getBoxHeight() { + return boxHeight; + } + public void setBoxHeight(double boxHeight) { + this.boxHeight = boxHeight; + } + public double getBoxLength() { + return boxLength; + } + public void setBoxLength(double boxLength) { + this.boxLength = boxLength; + } + public double getBoxWeight() { + return boxWeight; + } + public void setBoxWeight(double boxWeight) { + this.boxWeight = boxWeight; + } + public double getMaxWeight() { + return maxWeight; + } + public void setMaxWeight(double maxWeight) { + this.maxWeight = maxWeight; + } + + public boolean isDefaultPackaging() { + return defaultPackaging; + } + public void setDefaultPackaging(boolean defaultPackaging) { + this.defaultPackaging = defaultPackaging; + } + public ShippingPackageType getShipPackageType() { + return shipPackageType; + } + public void setShipPackageType(ShippingPackageType shipPackageType) { + this.shipPackageType = shipPackageType; + } + private String code; + private double boxWidth = 0; + private double boxHeight = 0; + private double boxLength = 0; + private double boxWeight = 0; + private double maxWeight = 0; + //private int shippingQuantity; + private int treshold; + private ShippingPackageType shipPackageType; + private boolean defaultPackaging; + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/PackageDetails.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/PackageDetails.java new file mode 100755 index 0000000000..b6b4d84eda --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/PackageDetails.java @@ -0,0 +1,80 @@ +package com.salesmanager.core.model.shipping; + +public class PackageDetails { + + private String code; + private double shippingWeight; + private double shippingMaxWeight; + private double shippingLength; + private double shippingHeight; + private double shippingWidth; + private int shippingQuantity; + private int treshold; + private String type; //BOX, ITEM + + + private String itemName = ""; + + + public String getItemName() { + return itemName; + } + public void setItemName(String itemName) { + this.itemName = itemName; + } + public double getShippingWeight() { + return shippingWeight; + } + public void setShippingWeight(double shippingWeight) { + this.shippingWeight = shippingWeight; + } + public double getShippingMaxWeight() { + return shippingMaxWeight; + } + public void setShippingMaxWeight(double shippingMaxWeight) { + this.shippingMaxWeight = shippingMaxWeight; + } + public double getShippingLength() { + return shippingLength; + } + public void setShippingLength(double shippingLength) { + this.shippingLength = shippingLength; + } + public double getShippingHeight() { + return shippingHeight; + } + public void setShippingHeight(double shippingHeight) { + this.shippingHeight = shippingHeight; + } + public double getShippingWidth() { + return shippingWidth; + } + public void setShippingWidth(double shippingWidth) { + this.shippingWidth = shippingWidth; + } + public int getShippingQuantity() { + return shippingQuantity; + } + public void setShippingQuantity(int shippingQuantity) { + this.shippingQuantity = shippingQuantity; + } + public int getTreshold() { + return treshold; + } + public void setTreshold(int treshold) { + this.treshold = treshold; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/Quote.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/Quote.java new file mode 100755 index 0000000000..d6237bacfd --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/Quote.java @@ -0,0 +1,222 @@ +package com.salesmanager.core.model.shipping; + +import java.math.BigDecimal; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.generic.SalesManagerEntity; + + +/** + * Shipping quote received from external shipping quote module or calculated internally + * @author c.samson + * + */ + +@Entity +@Table (name="SHIPPING_QUOTE" ) +public class Quote extends SalesManagerEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + @Id + @Column(name = "SHIPPING_QUOTE_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "SHIP_QUOTE_ID_NEXT_VALUE") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + Long id; + + @Column(name = "ORDER_ID", nullable = true) + private Long orderId; + + @Column(name = "CUSTOMER_ID", nullable = true) + private Long customerId; + + @Column(name = "CART_ID", nullable = true) + private Long cartId; + + @Column(name = "MODULE", nullable = false) + private String module; + + @Column(name = "OPTION_NAME", nullable = true) + private String optionName = null; + + @Column(name = "OPTION_CODE", nullable = true) + private String optionCode = null; + + @Temporal(TemporalType.TIMESTAMP) + @Column (name ="OPTION_DELIVERY_DATE") + private Date optionDeliveryDate = null; + + @Temporal(TemporalType.TIMESTAMP) + @Column (name ="OPTION_SHIPPING_DATE") + private Date optionShippingDate = null; + + @Temporal(TemporalType.TIMESTAMP) + @Column (name ="QUOTE_DATE") + private Date quoteDate; + + @Column(name = "SHIPPING_NUMBER_DAYS") + private Integer estimatedNumberOfDays; + + @Column (name ="QUOTE_PRICE") + private BigDecimal price = null; + + @Column (name ="QUOTE_HANDLING") + private BigDecimal handling = null; + + @Column(name = "FREE_SHIPPING") + private boolean freeShipping; + + @Column (name ="IP_ADDRESS") + private String ipAddress; + + @Embedded + private Delivery delivery = null; + + public Long getOrderId() { + return orderId; + } + + public void setOrderId(Long orderId) { + this.orderId = orderId; + } + + public Long getCustomerId() { + return customerId; + } + + public void setCustomerId(Long customerId) { + this.customerId = customerId; + } + + public String getModule() { + return module; + } + + public void setModule(String module) { + this.module = module; + } + + public String getOptionName() { + return optionName; + } + + public void setOptionName(String optionName) { + this.optionName = optionName; + } + + public String getOptionCode() { + return optionCode; + } + + public void setOptionCode(String optionCode) { + this.optionCode = optionCode; + } + + public Date getOptionDeliveryDate() { + return optionDeliveryDate; + } + + public void setOptionDeliveryDate(Date optionDeliveryDate) { + this.optionDeliveryDate = optionDeliveryDate; + } + + public Date getOptionShippingDate() { + return optionShippingDate; + } + + public void setOptionShippingDate(Date optionShippingDate) { + this.optionShippingDate = optionShippingDate; + } + + public Date getQuoteDate() { + return quoteDate; + } + + public void setQuoteDate(Date quoteDate) { + this.quoteDate = quoteDate; + } + + public Integer getEstimatedNumberOfDays() { + return estimatedNumberOfDays; + } + + public void setEstimatedNumberOfDays(Integer estimatedNumberOfDays) { + this.estimatedNumberOfDays = estimatedNumberOfDays; + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public Delivery getDelivery() { + return delivery; + } + + public void setDelivery(Delivery delivery) { + this.delivery = delivery; + } + + public boolean isFreeShipping() { + return freeShipping; + } + + public void setFreeShipping(boolean freeShipping) { + this.freeShipping = freeShipping; + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + + } + + public BigDecimal getHandling() { + return handling; + } + + public void setHandling(BigDecimal handling) { + this.handling = handling; + } + + public Long getCartId() { + return cartId; + } + + public void setCartId(Long cartId) { + this.cartId = cartId; + } + + public String getIpAddress() { + return ipAddress; + } + + public void setIpAddress(String ipAddress) { + this.ipAddress = ipAddress; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingBasisType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingBasisType.java new file mode 100755 index 0000000000..742b79067f --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingBasisType.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.shipping; + +public enum ShippingBasisType { + + BILLING, SHIPPING + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingConfiguration.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingConfiguration.java new file mode 100755 index 0000000000..963b340615 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingConfiguration.java @@ -0,0 +1,401 @@ +package com.salesmanager.core.model.shipping; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import org.json.simple.JSONArray; +import org.json.simple.JSONAware; +import org.json.simple.JSONObject; + +/** + * Object saved in the database maintaining various shipping options + * @author casams1 + * + */ +public class ShippingConfiguration implements JSONAware { + + //enums + private ShippingType shippingType = ShippingType.NATIONAL; + private ShippingBasisType shippingBasisType = ShippingBasisType.SHIPPING; + private ShippingOptionPriceType shippingOptionPriceType = ShippingOptionPriceType.ALL; + private ShippingPackageType shippingPackageType = ShippingPackageType.ITEM; + private ShippingDescription shippingDescription = ShippingDescription.SHORT_DESCRIPTION; + private ShippingType freeShippingType = null; + + private int boxWidth = 0; + private int boxHeight = 0; + private int boxLength = 0; + private double boxWeight = 0; + private double maxWeight = 0; + + //free shipping + private boolean freeShippingEnabled = false; + private BigDecimal orderTotalFreeShipping = null; + + private List packages = new ArrayList(); + + + + private BigDecimal handlingFees = null; + private boolean taxOnShipping = false; + + + //JSON bindings + private String shipType; + private String shipBaseType; + private String shipOptionPriceType = ShippingOptionPriceType.ALL.name(); + private String shipPackageType; + private String shipDescription; + private String shipFreeType; + + //Transient + private String orderTotalFreeShippingText = null; + private String handlingFeesText = null; + + + public String getShipType() { + return shipType; + } + + + public String getShipBaseType() { + return shipBaseType; + } + + + public String getShipOptionPriceType() { + return shipOptionPriceType; + } + + + + public void setShippingOptionPriceType(ShippingOptionPriceType shippingOptionPriceType) { + this.shippingOptionPriceType = shippingOptionPriceType; + this.shipOptionPriceType = this.shippingOptionPriceType.name(); + } + + + public ShippingOptionPriceType getShippingOptionPriceType() { + return shippingOptionPriceType; + } + + + public void setShippingBasisType(ShippingBasisType shippingBasisType) { + this.shippingBasisType = shippingBasisType; + this.shipBaseType = this.shippingBasisType.name(); + } + + + public ShippingBasisType getShippingBasisType() { + return shippingBasisType; + } + + + public void setShippingType(ShippingType shippingType) { + this.shippingType = shippingType; + this.shipType = this.shippingType.name(); + } + + + public ShippingType getShippingType() { + return shippingType; + } + + public ShippingPackageType getShippingPackageType() { + return shippingPackageType; + } + + + public void setShippingPackageType(ShippingPackageType shippingPackageType) { + this.shippingPackageType = shippingPackageType; + this.shipPackageType = shippingPackageType.name(); + } + + + public String getShipPackageType() { + return shipPackageType; + } + + + /** JSON bindding **/ + public void setShipType(String shipType) { + this.shipType = shipType; + ShippingType sType = ShippingType.NATIONAL; + if(shipType.equals(ShippingType.INTERNATIONAL.name())) { + sType = ShippingType.INTERNATIONAL; + } + setShippingType(sType); + } + + + public void setShipOptionPriceType(String shipOptionPriceType) { + this.shipOptionPriceType = shipOptionPriceType; + ShippingOptionPriceType sType = ShippingOptionPriceType.ALL; + if(shipOptionPriceType.equals(ShippingOptionPriceType.HIGHEST.name())) { + sType = ShippingOptionPriceType.HIGHEST; + } + if(shipOptionPriceType.equals(ShippingOptionPriceType.LEAST.name())) { + sType = ShippingOptionPriceType.LEAST; + } + setShippingOptionPriceType(sType); + } + + + public void setShipBaseType(String shipBaseType) { + this.shipBaseType = shipBaseType; + ShippingBasisType sType = ShippingBasisType.SHIPPING; + if(shipBaseType.equals(ShippingBasisType.BILLING.name())) { + sType = ShippingBasisType.BILLING; + } + setShippingBasisType(sType); + } + + + + public void setShipPackageType(String shipPackageType) { + this.shipPackageType = shipPackageType; + ShippingPackageType sType = ShippingPackageType.ITEM; + if(shipPackageType.equals(ShippingPackageType.BOX.name())) { + sType = ShippingPackageType.BOX; + } + this.setShippingPackageType(sType); + } + + public void setShipDescription(String shipDescription) { + this.shipDescription = shipDescription; + ShippingDescription sType = ShippingDescription.SHORT_DESCRIPTION; + if(shipDescription.equals(ShippingDescription.LONG_DESCRIPTION.name())) { + sType = ShippingDescription.LONG_DESCRIPTION; + } + this.setShippingDescription(sType); + } + + public void setShipFreeType(String shipFreeType) { + this.shipFreeType = shipFreeType; + ShippingType sType = ShippingType.NATIONAL; + if(shipFreeType.equals(ShippingType.INTERNATIONAL.name())) { + sType = ShippingType.INTERNATIONAL; + } + setFreeShippingType(sType); + } + + @SuppressWarnings("unchecked") + @Override + public String toJSONString() { + JSONObject data = new JSONObject(); + data.put("shipBaseType", this.getShippingBasisType().name()); + data.put("shipOptionPriceType", this.getShippingOptionPriceType().name()); + data.put("shipType", this.getShippingType().name()); + data.put("shipPackageType", this.getShippingPackageType().name()); + if(shipFreeType!=null) { + data.put("shipFreeType", this.getFreeShippingType().name()); + } + data.put("shipDescription", this.getShippingDescription().name()); + + + data.put("boxWidth", this.getBoxWidth()); + data.put("boxHeight", this.getBoxHeight()); + data.put("boxLength", this.getBoxLength()); + data.put("boxWeight", this.getBoxWeight()); + data.put("maxWeight", this.getMaxWeight()); + data.put("freeShippingEnabled", this.freeShippingEnabled); + data.put("orderTotalFreeShipping", this.orderTotalFreeShipping); + data.put("handlingFees", this.handlingFees); + data.put("taxOnShipping", this.taxOnShipping); + + + JSONArray jsonArray = new JSONArray(); + + for(Package p : this.getPackages()) { + jsonArray.add(transformPackage(p)); + } + + data.put("packages", jsonArray); + + + return data.toJSONString(); + } + + @SuppressWarnings("unchecked") + private JSONObject transformPackage(Package p) { + JSONObject data = new JSONObject(); + data.put("boxWidth", p.getBoxWidth()); + data.put("boxHeight", p.getBoxHeight()); + data.put("boxLength", p.getBoxLength()); + data.put("boxWeight", p.getBoxWeight()); + data.put("maxWeight", p.getMaxWeight()); + data.put("treshold", p.getTreshold()); + data.put("code", p.getCode()); + data.put("shipPackageType", p.getShipPackageType().name()); + data.put("defaultPackaging", p.isDefaultPackaging()); + return data; + } + + + public int getBoxWidth() { + return boxWidth; + } + + + public void setBoxWidth(int boxWidth) { + this.boxWidth = boxWidth; + } + + + public int getBoxHeight() { + return boxHeight; + } + + + public void setBoxHeight(int boxHeight) { + this.boxHeight = boxHeight; + } + + + public int getBoxLength() { + return boxLength; + } + + + public void setBoxLength(int boxLength) { + this.boxLength = boxLength; + } + + + public double getBoxWeight() { + return boxWeight; + } + + + public void setBoxWeight(double boxWeight) { + this.boxWeight = boxWeight; + } + + + public double getMaxWeight() { + return maxWeight; + } + + + public void setMaxWeight(double maxWeight) { + this.maxWeight = maxWeight; + } + + + public boolean isFreeShippingEnabled() { + return freeShippingEnabled; + } + + + public void setFreeShippingEnabled(boolean freeShippingEnabled) { + this.freeShippingEnabled = freeShippingEnabled; + } + + + public BigDecimal getOrderTotalFreeShipping() { + return orderTotalFreeShipping; + } + + + public void setOrderTotalFreeShipping(BigDecimal orderTotalFreeShipping) { + this.orderTotalFreeShipping = orderTotalFreeShipping; + } + + + public void setHandlingFees(BigDecimal handlingFees) { + this.handlingFees = handlingFees; + } + + + public BigDecimal getHandlingFees() { + return handlingFees; + } + + + public void setTaxOnShipping(boolean taxOnShipping) { + this.taxOnShipping = taxOnShipping; + } + + + public boolean isTaxOnShipping() { + return taxOnShipping; + } + + + + + + public String getShipDescription() { + return shipDescription; + } + + + public void setShippingDescription(ShippingDescription shippingDescription) { + this.shippingDescription = shippingDescription; + } + + + public ShippingDescription getShippingDescription() { + return shippingDescription; + } + + + public void setFreeShippingType(ShippingType freeShippingType) { + this.freeShippingType = freeShippingType; + } + + + public ShippingType getFreeShippingType() { + return freeShippingType; + } + + + + public String getShipFreeType() { + return shipFreeType; + } + + + public void setOrderTotalFreeShippingText(String orderTotalFreeShippingText) { + this.orderTotalFreeShippingText = orderTotalFreeShippingText; + } + + + public String getOrderTotalFreeShippingText() { + return orderTotalFreeShippingText; + } + + + public void setHandlingFeesText(String handlingFeesText) { + this.handlingFeesText = handlingFeesText; + } + + + public String getHandlingFeesText() { + return handlingFeesText; + } + + + public List getPackages() { + return packages; + } + + + public void setPackages(List packages) { + this.packages = packages; + } + + + + + + + + + + + +} + + diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingDescription.java new file mode 100755 index 0000000000..7ae33ad4eb --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingDescription.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.shipping; + +public enum ShippingDescription { + + + SHORT_DESCRIPTION, LONG_DESCRIPTION +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingMetaData.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingMetaData.java new file mode 100755 index 0000000000..f196d55c80 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingMetaData.java @@ -0,0 +1,60 @@ +package com.salesmanager.core.model.shipping; + +import java.util.List; + +import com.salesmanager.core.model.reference.country.Country; + +/** + * Describes how shipping is configured for a given store + * @author carlsamson + * + */ +public class ShippingMetaData { + + private List modules; + private List preProcessors; + private List postProcessors; + private List shipToCountry; + private boolean useDistanceModule; + private boolean useAddressAutoComplete; + + + + public List getModules() { + return modules; + } + public void setModules(List modules) { + this.modules = modules; + } + public List getPreProcessors() { + return preProcessors; + } + public void setPreProcessors(List preProcessors) { + this.preProcessors = preProcessors; + } + public List getPostProcessors() { + return postProcessors; + } + public void setPostProcessors(List postProcessors) { + this.postProcessors = postProcessors; + } + public List getShipToCountry() { + return shipToCountry; + } + public void setShipToCountry(List shipToCountry) { + this.shipToCountry = shipToCountry; + } + public boolean isUseDistanceModule() { + return useDistanceModule; + } + public void setUseDistanceModule(boolean useDistanceModule) { + this.useDistanceModule = useDistanceModule; + } + public boolean isUseAddressAutoComplete() { + return useAddressAutoComplete; + } + public void setUseAddressAutoComplete(boolean useAddressAutoComplete) { + this.useAddressAutoComplete = useAddressAutoComplete; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingOption.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingOption.java new file mode 100755 index 0000000000..3b7d79c441 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingOption.java @@ -0,0 +1,127 @@ +package com.salesmanager.core.model.shipping; + +import java.io.Serializable; +import java.math.BigDecimal; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ShippingOption implements Serializable { + + private static final Logger LOGGER = LoggerFactory.getLogger(ShippingOption.class); + + /** + * + */ + private static final long serialVersionUID = 1L; + private BigDecimal optionPrice; + private Long shippingQuoteOptionId; + + + private String optionName = null; + private String optionCode = null; + private String optionDeliveryDate = null; + private String optionShippingDate = null; + private String optionPriceText = null; + private String optionId = null; + private String description = null; + private String shippingModuleCode = null; + private String note = null; + + private String estimatedNumberOfDays; + + + + public BigDecimal getOptionPrice() { + + if(optionPrice == null && !StringUtils.isBlank(this.getOptionPriceText())) {//if price text only is available, try to parse it + try { + this.optionPrice = new BigDecimal(this.getOptionPriceText()); + } catch(Exception e) { + LOGGER.error("Can't convert price text " + this.getOptionPriceText() + " to big decimal"); + } + } + + return optionPrice; + } + + public void setOptionPrice(BigDecimal optionPrice) { + this.optionPrice = optionPrice; + } + + public void setOptionCode(String optionCode) { + this.optionCode = optionCode; + } + public String getOptionCode() { + return optionCode; + } + public void setOptionName(String optionName) { + this.optionName = optionName; + } + public String getOptionName() { + return optionName; + } + + public void setOptionPriceText(String optionPriceText) { + this.optionPriceText = optionPriceText; + } + public String getOptionPriceText() { + return optionPriceText; + } + public void setOptionId(String optionId) { + this.optionId = optionId; + } + public String getOptionId() { + return optionId; + } + public void setOptionDeliveryDate(String optionDeliveryDate) { + this.optionDeliveryDate = optionDeliveryDate; + } + public String getOptionDeliveryDate() { + return optionDeliveryDate; + } + public void setOptionShippingDate(String optionShippingDate) { + this.optionShippingDate = optionShippingDate; + } + public String getOptionShippingDate() { + return optionShippingDate; + } + public void setDescription(String description) { + this.description = description; + } + public String getDescription() { + return description; + } + public void setEstimatedNumberOfDays(String estimatedNumberOfDays) { + this.estimatedNumberOfDays = estimatedNumberOfDays; + } + public String getEstimatedNumberOfDays() { + return estimatedNumberOfDays; + } + + public String getShippingModuleCode() { + return shippingModuleCode; + } + + public void setShippingModuleCode(String shippingModuleCode) { + this.shippingModuleCode = shippingModuleCode; + } + + public String getNote() { + return note; + } + + public void setNote(String note) { + this.note = note; + } + + public Long getShippingQuoteOptionId() { + return shippingQuoteOptionId; + } + + public void setShippingQuoteOptionId(Long shippingQuoteOptionId) { + this.shippingQuoteOptionId = shippingQuoteOptionId; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingOptionPriceType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingOptionPriceType.java new file mode 100755 index 0000000000..da7698231c --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingOptionPriceType.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.shipping; + +public enum ShippingOptionPriceType { + + LEAST, HIGHEST, ALL + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingOrigin.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingOrigin.java new file mode 100755 index 0000000000..41bfe6fb60 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingOrigin.java @@ -0,0 +1,149 @@ +package com.salesmanager.core.model.shipping; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import javax.validation.constraints.NotEmpty; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.zone.Zone; + +@Entity +@Table(name = "SHIPING_ORIGIN") +public class ShippingOrigin extends SalesManagerEntity { + + + /** + * + */ + private static final long serialVersionUID = 1172536723717691214L; + + + @Id + @Column(name = "SHIP_ORIGIN_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", + pkColumnValue = "SHP_ORIG_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Column(name = "ACTIVE") + private boolean active; + + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore merchantStore; + + @NotEmpty + @Column (name ="STREET_ADDRESS", length=256) + private String address; + + + @NotEmpty + @Column (name ="CITY", length=100) + private String city; + + @NotEmpty + @Column (name ="POSTCODE", length=20) + private String postalCode; + + @Column (name ="STATE", length=100) + private String state; + + @ManyToOne(fetch = FetchType.EAGER, targetEntity = Country.class) + @JoinColumn(name="COUNTRY_ID", nullable=true) + private Country country; + + @ManyToOne(fetch = FetchType.EAGER, targetEntity = Zone.class) + @JoinColumn(name="ZONE_ID", nullable=true) + private Zone zone; + + @Override + public Long getId() { + return this.id; + } + + @Override + public void setId(Long id) { + this.id = id; + + } + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public Country getCountry() { + return country; + } + + public void setCountry(Country country) { + this.country = country; + } + + public Zone getZone() { + return zone; + } + + public void setZone(Zone zone) { + this.zone = zone; + } + + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingPackageType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingPackageType.java new file mode 100755 index 0000000000..71f0f51cd6 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingPackageType.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.shipping; + +public enum ShippingPackageType { + + ITEM, BOX + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingProduct.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingProduct.java new file mode 100755 index 0000000000..ae2aeea697 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingProduct.java @@ -0,0 +1,39 @@ +package com.salesmanager.core.model.shipping; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; + +public class ShippingProduct { + + public ShippingProduct(Product product) { + this.product = product; + + } + + private int quantity = 1; + private Product product; + + private FinalPrice finalPrice; + + + + public void setQuantity(int quantity) { + this.quantity = quantity; + } + public int getQuantity() { + return quantity; + } + public void setProduct(Product product) { + this.product = product; + } + public Product getProduct() { + return product; + } + public FinalPrice getFinalPrice() { + return finalPrice; + } + public void setFinalPrice(FinalPrice finalPrice) { + this.finalPrice = finalPrice; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingQuote.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingQuote.java new file mode 100755 index 0000000000..5dca27f8e2 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingQuote.java @@ -0,0 +1,138 @@ +package com.salesmanager.core.model.shipping; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.system.IntegrationModule; + +public class ShippingQuote implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + public final static String NO_SHIPPING_TO_SELECTED_COUNTRY = "NO_SHIPPING_TO_SELECTED_COUNTRY"; + public final static String NO_SHIPPING_MODULE_CONFIGURED= "NO_SHIPPING_MODULE_CONFIGURED"; + public final static String NO_POSTAL_CODE= "NO_POSTAL_CODE"; + public final static String ERROR= "ERROR"; + + /** shipping module used **/ + private String shippingModuleCode; + private List shippingOptions = null; + /** if an error occurs, this field will be populated from constants defined above **/ + private String shippingReturnCode = null;//NO_SHIPPING... or NO_SHIPPING_MODULE... or NO_POSTAL_... + /** indicates if this quote is configured with free shipping **/ + private boolean freeShipping; + /** the threshold amount for being free shipping **/ + private BigDecimal freeShippingAmount; + /** handling fees to be added on top of shipping fees **/ + private BigDecimal handlingFees; + /** apply tax on shipping **/ + private boolean applyTaxOnShipping; + + /** + * final delivery address + */ + private Delivery deliveryAddress; + + private List warnings = new ArrayList(); + + private ShippingOption selectedShippingOption = null; + + private IntegrationModule currentShippingModule; + + private String quoteError = null; + + /** additinal shipping information **/ + private Map quoteInformations = new HashMap(); + + + + public void setShippingOptions(List shippingOptions) { + this.shippingOptions = shippingOptions; + } + public List getShippingOptions() { + return shippingOptions; + } + public void setShippingModuleCode(String shippingModuleCode) { + this.shippingModuleCode = shippingModuleCode; + } + public String getShippingModuleCode() { + return shippingModuleCode; + } + public void setShippingReturnCode(String shippingReturnCode) { + this.shippingReturnCode = shippingReturnCode; + } + public String getShippingReturnCode() { + return shippingReturnCode; + } + public void setFreeShipping(boolean freeShipping) { + this.freeShipping = freeShipping; + } + public boolean isFreeShipping() { + return freeShipping; + } + public void setFreeShippingAmount(BigDecimal freeShippingAmount) { + this.freeShippingAmount = freeShippingAmount; + } + public BigDecimal getFreeShippingAmount() { + return freeShippingAmount; + } + public void setHandlingFees(BigDecimal handlingFees) { + this.handlingFees = handlingFees; + } + public BigDecimal getHandlingFees() { + return handlingFees; + } + public void setApplyTaxOnShipping(boolean applyTaxOnShipping) { + this.applyTaxOnShipping = applyTaxOnShipping; + } + public boolean isApplyTaxOnShipping() { + return applyTaxOnShipping; + } + public void setSelectedShippingOption(ShippingOption selectedShippingOption) { + this.selectedShippingOption = selectedShippingOption; + } + public ShippingOption getSelectedShippingOption() { + return selectedShippingOption; + } + public String getQuoteError() { + return quoteError; + } + public void setQuoteError(String quoteError) { + this.quoteError = quoteError; + } + public Map getQuoteInformations() { + return quoteInformations; + } + public void setQuoteInformations(Map quoteInformations) { + this.quoteInformations = quoteInformations; + } + public IntegrationModule getCurrentShippingModule() { + return currentShippingModule; + } + public void setCurrentShippingModule(IntegrationModule currentShippingModule) { + this.currentShippingModule = currentShippingModule; + } + public List getWarnings() { + return warnings; + } + public void setWarnings(List warnings) { + this.warnings = warnings; + } + public Delivery getDeliveryAddress() { + return deliveryAddress; + } + public void setDeliveryAddress(Delivery deliveryAddress) { + this.deliveryAddress = deliveryAddress; + } + + + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingSummary.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingSummary.java new file mode 100755 index 0000000000..4f73e65a84 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingSummary.java @@ -0,0 +1,86 @@ +package com.salesmanager.core.model.shipping; + +import java.io.Serializable; +import java.math.BigDecimal; + +import com.salesmanager.core.model.common.Delivery; + +/** + * Contains shipping fees according to user selections + * @author casams1 + * + */ +public class ShippingSummary implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private BigDecimal shipping; + private BigDecimal handling; + private String shippingModule; + private String shippingOption; + private String shippingOptionCode; + private boolean freeShipping; + private boolean taxOnShipping; + private boolean shippingQuote; + + private Delivery deliveryAddress; + + + public BigDecimal getShipping() { + return shipping; + } + public void setShipping(BigDecimal shipping) { + this.shipping = shipping; + } + public BigDecimal getHandling() { + return handling; + } + public void setHandling(BigDecimal handling) { + this.handling = handling; + } + public String getShippingModule() { + return shippingModule; + } + public void setShippingModule(String shippingModule) { + this.shippingModule = shippingModule; + } + public String getShippingOption() { + return shippingOption; + } + public void setShippingOption(String shippingOption) { + this.shippingOption = shippingOption; + } + public boolean isFreeShipping() { + return freeShipping; + } + public void setFreeShipping(boolean freeShipping) { + this.freeShipping = freeShipping; + } + public boolean isTaxOnShipping() { + return taxOnShipping; + } + public void setTaxOnShipping(boolean taxOnShipping) { + this.taxOnShipping = taxOnShipping; + } + public Delivery getDeliveryAddress() { + return deliveryAddress; + } + public void setDeliveryAddress(Delivery deliveryAddress) { + this.deliveryAddress = deliveryAddress; + } + public String getShippingOptionCode() { + return shippingOptionCode; + } + public void setShippingOptionCode(String shippingOptionCode) { + this.shippingOptionCode = shippingOptionCode; + } + public boolean isShippingQuote() { + return shippingQuote; + } + public void setShippingQuote(boolean shippingQuote) { + this.shippingQuote = shippingQuote; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingType.java new file mode 100755 index 0000000000..cd69384901 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shipping/ShippingType.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.shipping; + +public enum ShippingType { + + NATIONAL, INTERNATIONAL + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shoppingcart/ShoppingCart.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shoppingcart/ShoppingCart.java new file mode 100755 index 0000000000..a7fb41c8b9 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shoppingcart/ShoppingCart.java @@ -0,0 +1,191 @@ +/** + * + */ +package com.salesmanager.core.model.shoppingcart; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Transient; + +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + +/** + *

Shopping cart is responsible for storing and carrying + * shopping cart information.Shopping Cart consists of {@link ShoppingCartItem} + * which represents individual lines items associated with the shopping cart

+ * @author Umesh Awasthi + * version 2.0 + * + */ +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "SHOPPING_CART", indexes= { @Index(name = "SHP_CART_CODE_IDX", columnList = "SHP_CART_CODE"), @Index(name = "SHP_CART_CUSTOMER_IDX", columnList = "CUSTOMER_ID")}) +public class ShoppingCart extends SalesManagerEntity implements Auditable{ + + + private static final long serialVersionUID = 1L; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @Id + @Column(name = "SHP_CART_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "SHP_CRT_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + /** + * Will be used to fetch shopping cart model from the controller + * this is a unique code that should be attributed from the client (UI) + * + */ + @Column(name = "SHP_CART_CODE", unique=true, nullable=false) + private String shoppingCartCode; + + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "shoppingCart") + private Set lineItems = new HashSet(); + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore merchantStore; + + @Column(name = "CUSTOMER_ID", nullable = true) + private Long customerId; + + @Column(name = "ORDER_ID", nullable = true) + private Long orderId; + + @Column (name ="IP_ADDRESS") + private String ipAddress; + + @Column (name ="PROMO_CODE") + private String promoCode; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "PROMO_ADDED") + private Date promoAdded; + + @Transient + private boolean obsolete = false;//when all items are obsolete + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection audit) { + this.auditSection = audit; + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + + } + + public boolean isObsolete() { + return obsolete; + } + + public void setObsolete(boolean obsolete) { + this.obsolete = obsolete; + } + + public Set getLineItems() { + return lineItems; + } + + public void setLineItems(Set lineItems) { + this.lineItems = lineItems; + } + + public String getShoppingCartCode() + { + return shoppingCartCode; + } + + public void setShoppingCartCode( String shoppingCartCode ) + { + this.shoppingCartCode = shoppingCartCode; + } + + public void setCustomerId(Long customerId) { + this.customerId = customerId; + } + + public Long getCustomerId() { + return customerId; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public String getIpAddress() { + return ipAddress; + } + + public void setIpAddress(String ipAddress) { + this.ipAddress = ipAddress; + } + + + public String getPromoCode() { + return promoCode; + } + + public void setPromoCode(String promoCode) { + this.promoCode = promoCode; + } + + public Date getPromoAdded() { + return promoAdded; + } + + public void setPromoAdded(Date promoAdded) { + this.promoAdded = promoAdded; + } + + public Long getOrderId() { + return orderId; + } + + public void setOrderId(Long orderId) { + this.orderId = orderId; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shoppingcart/ShoppingCartAttributeItem.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shoppingcart/ShoppingCartAttributeItem.java new file mode 100755 index 0000000000..af0a84631d --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shoppingcart/ShoppingCartAttributeItem.java @@ -0,0 +1,120 @@ +package com.salesmanager.core.model.shoppingcart; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Transient; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; + + +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "SHOPPING_CART_ATTR_ITEM") +public class ShoppingCartAttributeItem extends SalesManagerEntity implements Auditable { + + + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "SHP_CART_ATTR_ITEM_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "SHP_CRT_ATTR_ITM_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + + + @Column(name="PRODUCT_ATTR_ID", nullable=false) + private Long productAttributeId; + + @JsonIgnore + @Transient + private ProductAttribute productAttribute; + + + @JsonIgnore + @ManyToOne(targetEntity = ShoppingCartItem.class) + @JoinColumn(name = "SHP_CART_ITEM_ID", nullable = false) + private ShoppingCartItem shoppingCartItem; + + public ShoppingCartAttributeItem(ShoppingCartItem shoppingCartItem, ProductAttribute productAttribute) { + this.shoppingCartItem = shoppingCartItem; + this.productAttribute = productAttribute; + this.productAttributeId = productAttribute.getId(); + } + + public ShoppingCartAttributeItem(ShoppingCartItem shoppingCartItem, Long productAttributeId) { + this.shoppingCartItem = shoppingCartItem; + this.productAttributeId = productAttributeId; + } + + public ShoppingCartAttributeItem() { + + } + + + public ShoppingCartItem getShoppingCartItem() { + return shoppingCartItem; + } + + public void setShoppingCartItem(ShoppingCartItem shoppingCartItem) { + this.shoppingCartItem = shoppingCartItem; + } + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection audit) { + this.auditSection = audit; + + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + + } + + + public void setProductAttributeId(Long productAttributeId) { + this.productAttributeId = productAttributeId; + } + + public Long getProductAttributeId() { + return productAttributeId; + } + + public void setProductAttribute(ProductAttribute productAttribute) { + this.productAttribute = productAttribute; + } + + public ProductAttribute getProductAttribute() { + return productAttribute; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/shoppingcart/ShoppingCartItem.java b/sm-core-model/src/main/java/com/salesmanager/core/model/shoppingcart/ShoppingCartItem.java new file mode 100755 index 0000000000..7a30efca90 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/shoppingcart/ShoppingCartItem.java @@ -0,0 +1,251 @@ +package com.salesmanager.core.model.shoppingcart; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Transient; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; + + +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "SHOPPING_CART_ITEM") +public class ShoppingCartItem extends SalesManagerEntity implements Auditable, Serializable { + + + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "SHP_CART_ITEM_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "SHP_CRT_ITM_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @JsonIgnore + @ManyToOne(targetEntity = ShoppingCart.class) + @JoinColumn(name = "SHP_CART_ID", nullable = false) + private ShoppingCart shoppingCart; + + @Column(name="QUANTITY") + private Integer quantity = 1; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @Deprecated //Use sku + @Column(name="PRODUCT_ID", nullable=false) + private Long productId; + + //SKU + @Column(name="SKU", nullable=true) + private String sku; + + @JsonIgnore + @Transient + private boolean productVirtual; + + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "shoppingCartItem") + private Set attributes = new HashSet(); + + @Column(name="PRODUCT_VARIANT", nullable=true) + private Long variant; + + @JsonIgnore + @Transient + private BigDecimal itemPrice;//item final price including all rebates + + @JsonIgnore + @Transient + private BigDecimal subTotal;//item final price * quantity + + @JsonIgnore + @Transient + private FinalPrice finalPrice;//contains price details (raw prices) + + @JsonIgnore + @Transient + private Product product; + + @JsonIgnore + @Transient + private boolean obsolete = false; + + + + + public ShoppingCartItem(ShoppingCart shoppingCart, Product product) { + this(product); + this.shoppingCart = shoppingCart; + } + + public ShoppingCartItem(Product product) { + this.product = product; + this.productId = product.getId(); + this.setSku(product.getSku()); + this.quantity = 1; + this.productVirtual = product.isProductVirtual(); + } + + /** remove usage to limit possibility to implement bugs, would use constructors above to make sure all needed attributes are set correctly **/ + @Deprecated + public ShoppingCartItem() { + } + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection audit) { + this.auditSection = audit; + + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + + } + + public void setAttributes(Set attributes) { + this.attributes = attributes; + } + + public Set getAttributes() { + return attributes; + } + + public void setItemPrice(BigDecimal itemPrice) { + this.itemPrice = itemPrice; + } + + public BigDecimal getItemPrice() { + return itemPrice; + } + + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } + + public Integer getQuantity() { + return quantity; + } + + public ShoppingCart getShoppingCart() { + return shoppingCart; + } + + public void setShoppingCart(ShoppingCart shoppingCart) { + this.shoppingCart = shoppingCart; + } + + public void setProductId(Long productId) { + this.productId = productId; + } + + public Long getProductId() { + return productId; + } + + public void setProduct(Product product) { + this.product = product; + } + + public Product getProduct() { + return product; + } + + public void addAttributes(ShoppingCartAttributeItem shoppingCartAttributeItem) + { + this.attributes.add(shoppingCartAttributeItem); + } + + public void removeAttributes(ShoppingCartAttributeItem shoppingCartAttributeItem) + { + this.attributes.remove(shoppingCartAttributeItem); + } + + public void removeAllAttributes(){ + this.attributes.removeAll(Collections.EMPTY_SET); + } + + public void setSubTotal(BigDecimal subTotal) { + this.subTotal = subTotal; + } + + public BigDecimal getSubTotal() { + return subTotal; + } + + public void setFinalPrice(FinalPrice finalPrice) { + this.finalPrice = finalPrice; + } + + public FinalPrice getFinalPrice() { + return finalPrice; + } + + public boolean isObsolete() { + return obsolete; + } + + public void setObsolete(boolean obsolete) { + this.obsolete = obsolete; + } + + + public boolean isProductVirtual() { + return productVirtual; + } + + public void setProductVirtual(boolean productVirtual) { + this.productVirtual = productVirtual; + } + + public String getSku() { + return sku; + } + + public void setSku(String sku) { + this.sku = sku; + } + + public Long getVariant() { + return variant; + } + + public void setVariant(Long variant) { + this.variant = variant; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/system/CustomIntegrationConfiguration.java b/sm-core-model/src/main/java/com/salesmanager/core/model/system/CustomIntegrationConfiguration.java new file mode 100755 index 0000000000..0eaec187c2 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/system/CustomIntegrationConfiguration.java @@ -0,0 +1,14 @@ +package com.salesmanager.core.model.system; + +import org.json.simple.JSONAware; + +/** + * Used as a marker interface to commit additional + * integration module information to the database + * @author casams1 + * + */ +public interface CustomIntegrationConfiguration extends JSONAware{ + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/system/Environment.java b/sm-core-model/src/main/java/com/salesmanager/core/model/system/Environment.java new file mode 100755 index 0000000000..7893e9d705 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/system/Environment.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.system; + +public enum Environment { + + TEST, PRODUCTION + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/system/IntegrationConfiguration.java b/sm-core-model/src/main/java/com/salesmanager/core/model/system/IntegrationConfiguration.java new file mode 100755 index 0000000000..2c8279045b --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/system/IntegrationConfiguration.java @@ -0,0 +1,187 @@ +package com.salesmanager.core.model.system; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.json.simple.JSONAware; +import org.json.simple.JSONObject; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Object used to contain the integration information with an external gateway Uses simple JSON to + * encode the object in JSON by implementing JSONAware and uses jackson JSON decode to parse JSON + * String to an Object + * + * @author csamson + * + */ +public class IntegrationConfiguration implements JSONAware { + + + public final static String TEST_ENVIRONMENT = "TEST"; + public final static String PRODUCTION_ENVIRONMENT = "PRODUCTION"; + + private String moduleCode; + private boolean active; + private boolean defaultSelected; + private Map integrationKeys = new HashMap(); + private Map> integrationOptions = new HashMap>(); + private String environment; + + + public String getModuleCode() { + return moduleCode; + } + + @JsonProperty("moduleCode") + public void setModuleCode(String moduleCode) { + this.moduleCode = moduleCode; + } + + public boolean isActive() { + return active; + } + + @JsonProperty("active") + public void setActive(boolean active) { + this.active = active; + } + + public Map getIntegrationKeys() { + return integrationKeys; + } + + @JsonProperty("integrationKeys") + public void setIntegrationKeys(Map integrationKeys) { + this.integrationKeys = integrationKeys; + } + + + protected String getJsonInfo() { + + StringBuilder returnString = new StringBuilder(); + returnString.append("{"); + returnString.append("\"moduleCode\"").append(":\"").append(this.getModuleCode()).append("\""); + returnString.append(","); + returnString.append("\"active\"").append(":").append(this.isActive()); + returnString.append(","); + returnString.append("\"defaultSelected\"").append(":").append(this.isDefaultSelected()); + returnString.append(","); + returnString.append("\"environment\"").append(":\"").append(this.getEnvironment()).append("\""); + return returnString.toString(); + + } + + + @SuppressWarnings("unchecked") + @Override + public String toJSONString() { + + + StringBuilder returnString = new StringBuilder(); + returnString.append(getJsonInfo()); + + if (this.getIntegrationKeys().size() > 0) { + + JSONObject data = new JSONObject(); + Set keys = this.getIntegrationKeys().keySet(); + for (String key : keys) { + data.put(key, this.getIntegrationKeys().get(key)); + } + String dataField = data.toJSONString(); + + returnString.append(",").append("\"integrationKeys\"").append(":"); + returnString.append(dataField.toString()); + + + } + + + if (this.getIntegrationOptions() != null && this.getIntegrationOptions().size() > 0) { + + // JSONObject data = new JSONObject(); + StringBuilder optionDataEntries = new StringBuilder(); + Set keys = this.getIntegrationOptions().keySet(); + int countOptions = 0; + int keySize = 0; + + for (String key : keys) { + List values = this.getIntegrationOptions().get(key); + if (values != null) { + keySize++; + } + } + + for (String key : keys) { + + List values = this.getIntegrationOptions().get(key); + if (values == null) { + continue; + } + StringBuilder optionsEntries = new StringBuilder(); + StringBuilder dataEntries = new StringBuilder(); + + int count = 0; + for (String value : values) { + + dataEntries.append("\"").append(value).append("\""); + if (count < values.size() - 1) { + dataEntries.append(","); + } + count++; + } + + optionsEntries.append("[").append(dataEntries.toString()).append("]"); + + optionDataEntries.append("\"").append(key).append("\":").append(optionsEntries.toString()); + + if (countOptions < keySize - 1) { + optionDataEntries.append(","); + } + countOptions++; + + } + String dataField = optionDataEntries.toString(); + + returnString.append(",").append("\"integrationOptions\"").append(":{"); + returnString.append(dataField.toString()); + returnString.append("}"); + + } + + + returnString.append("}"); + + + return returnString.toString(); + + } + + public void setEnvironment(String environment) { + this.environment = environment; + } + + public String getEnvironment() { + return environment; + } + + public Map> getIntegrationOptions() { + return integrationOptions; + } + + public void setIntegrationOptions(Map> integrationOptions) { + this.integrationOptions = integrationOptions; + } + + public boolean isDefaultSelected() { + return defaultSelected; + } + + public void setDefaultSelected(boolean defaultSelected) { + this.defaultSelected = defaultSelected; + } + + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/system/IntegrationModule.java b/sm-core-model/src/main/java/com/salesmanager/core/model/system/IntegrationModule.java new file mode 100755 index 0000000000..534392fc13 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/system/IntegrationModule.java @@ -0,0 +1,221 @@ +package com.salesmanager.core.model.system; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Transient; + +import org.hibernate.annotations.Type; + +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; + +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "MODULE_CONFIGURATION", indexes = { + @Index(name = "MODULE_CONFIGURATION_MODULE", columnList = "MODULE") }) + +public class IntegrationModule extends SalesManagerEntity implements Serializable, Auditable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "MODULE_CONF_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "MOD_CONF_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Column(name = "MODULE") + private String module; + + @Column(name = "CODE", nullable = false) + private String code; + + @Column(name = "REGIONS") + private String regions; + + @Column(name = "CONFIGURATION", length=4000) + private String configuration; + + @Column(name = "DETAILS") + @Type(type = "org.hibernate.type.TextType") + private String configDetails; + + @Column(name = "TYPE") + private String type; + + @Column(name = "IMAGE") + private String image; + + @Column(name = "CUSTOM_IND") + private boolean customModule = false; + + @Transient + private Set regionsSet = new HashSet(); + + @Transient + private String binaryImage = null; + + /** + * Contains a map of module config by environment (DEV,PROD) + */ + @Transient + private Map moduleConfigs = new HashMap(); + + @Transient + private Map details = new HashMap(); + + /** + * A json tructure decribing how the module must be built + */ + @Transient + private String configurable = null; + + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection audit) { + this.auditSection = audit; + + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public String getModule() { + return module; + } + + public void setModule(String module) { + this.module = module; + } + + public String getRegions() { + return regions; + } + + public void setRegions(String regions) { + this.regions = regions; + } + + public String getConfiguration() { + return configuration; + } + + public void setConfiguration(String configuration) { + this.configuration = configuration; + } + + public void setRegionsSet(Set regionsSet) { + this.regionsSet = regionsSet; + } + + public Set getRegionsSet() { + return regionsSet; + } + + public void setCode(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + + public void setModuleConfigs(Map moduleConfigs) { + this.moduleConfigs = moduleConfigs; + } + + public Map getModuleConfigs() { + return moduleConfigs; + } + + public void setImage(String image) { + this.image = image; + } + + public String getImage() { + return image; + } + + public void setCustomModule(boolean customModule) { + this.customModule = customModule; + } + + public boolean isCustomModule() { + return customModule; + } + + public String getConfigDetails() { + return configDetails; + } + + public void setConfigDetails(String configDetails) { + this.configDetails = configDetails; + } + + public void setType(String type) { + this.type = type; + } + + public String getType() { + return type; + } + + public String getBinaryImage() { + return binaryImage; + } + + public void setBinaryImage(String binaryImage) { + this.binaryImage = binaryImage; + } + + public String getConfigurable() { + return configurable; + } + + public void setConfigurable(String configurable) { + this.configurable = configurable; + } + + public Map getDetails() { + return details; + } + + public void setDetails(Map details) { + this.details = details; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/system/MerchantConfig.java b/sm-core-model/src/main/java/com/salesmanager/core/model/system/MerchantConfig.java new file mode 100755 index 0000000000..9f4751eadd --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/system/MerchantConfig.java @@ -0,0 +1,174 @@ +package com.salesmanager.core.model.system; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONAware; +import org.json.simple.JSONObject; + +public class MerchantConfig implements Serializable, JSONAware { + + + /** + * TODO + * Add a generic key value in order to allow the creation of configuration + * on the fly from the client application and read from a key value map + */ + + private static final long serialVersionUID = 1L; + private boolean displayCustomerSection =false; + private boolean displayContactUs =false; + private boolean displayStoreAddress = false; + private boolean displayAddToCartOnFeaturedItems = false; + private boolean displayCustomerAgreement = false; + private boolean displayPagesMenu = true; + private boolean allowPurchaseItems = true; + private boolean displaySearchBox = true; + private boolean testMode = false; + private boolean debugMode = false; + + /** Store default search json config **/ + private Map useDefaultSearchConfig= new HashMap();//language code | true or false + private Map defaultSearchConfigPath= new HashMap();//language code | file path + + @SuppressWarnings("unchecked") + @Override + public String toJSONString() { + JSONObject data = new JSONObject(); + data.put("displayCustomerSection", this.isDisplayCustomerSection()); + data.put("displayContactUs", this.isDisplayContactUs()); + data.put("displayStoreAddress", this.isDisplayStoreAddress()); + data.put("displayAddToCartOnFeaturedItems", this.isDisplayAddToCartOnFeaturedItems()); + data.put("displayPagesMenu", this.isDisplayPagesMenu()); + data.put("displayCustomerAgreement", this.isDisplayCustomerAgreement()); + data.put("allowPurchaseItems", this.isAllowPurchaseItems()); + data.put("displaySearchBox", this.displaySearchBox); + data.put("testMode", this.isTestMode()); + data.put("debugMode", this.isDebugMode()); + + if(useDefaultSearchConfig!=null) { + JSONObject obj = new JSONObject(); + for(String key : useDefaultSearchConfig.keySet()) { + Boolean val = (Boolean)useDefaultSearchConfig.get(key); + if(val!=null) { + obj.put(key,val); + } + } + data.put("useDefaultSearchConfig", obj); + } + + if(defaultSearchConfigPath!=null) { + JSONObject obj = new JSONObject(); + for(String key : defaultSearchConfigPath.keySet()) { + String val = (String)defaultSearchConfigPath.get(key); + if(!StringUtils.isBlank(val)) { + obj.put(key, val); + } + } + data.put("defaultSearchConfigPath", obj); + } + + + return data.toJSONString(); + } + + public void setDisplayCustomerSection(boolean displayCustomerSection) { + this.displayCustomerSection = displayCustomerSection; + } + + public boolean isDisplayCustomerSection() { + return displayCustomerSection; + } + + public void setDisplayContactUs(boolean displayContactUs) { + this.displayContactUs = displayContactUs; + } + + public boolean isDisplayContactUs() { + return displayContactUs; + } + + public boolean isDisplayStoreAddress() { + return displayStoreAddress; + } + + public void setDisplayStoreAddress(boolean displayStoreAddress) { + this.displayStoreAddress = displayStoreAddress; + } + + public void setUseDefaultSearchConfig(Map useDefaultSearchConfig) { + this.useDefaultSearchConfig = useDefaultSearchConfig; + } + + public Map getUseDefaultSearchConfig() { + return useDefaultSearchConfig; + } + + public void setDefaultSearchConfigPath(Map defaultSearchConfigPath) { + this.defaultSearchConfigPath = defaultSearchConfigPath; + } + + public Map getDefaultSearchConfigPath() { + return defaultSearchConfigPath; + } + + public void setDisplayAddToCartOnFeaturedItems( + boolean displayAddToCartOnFeaturedItems) { + this.displayAddToCartOnFeaturedItems = displayAddToCartOnFeaturedItems; + } + + public boolean isDisplayAddToCartOnFeaturedItems() { + return displayAddToCartOnFeaturedItems; + } + + public boolean isDisplayCustomerAgreement() { + return displayCustomerAgreement; + } + + public void setDisplayCustomerAgreement(boolean displayCustomerAgreement) { + this.displayCustomerAgreement = displayCustomerAgreement; + } + + public boolean isAllowPurchaseItems() { + return allowPurchaseItems; + } + + public void setAllowPurchaseItems(boolean allowPurchaseItems) { + this.allowPurchaseItems = allowPurchaseItems; + } + + public boolean isDisplaySearchBox() { + return displaySearchBox; + } + + public void setDisplaySearchBox(boolean displaySearchBox) { + this.displaySearchBox = displaySearchBox; + } + + public boolean isTestMode() { + return testMode; + } + + public void setTestMode(boolean testMode) { + this.testMode = testMode; + } + + public boolean isDebugMode() { + return debugMode; + } + + public void setDebugMode(boolean debugMode) { + this.debugMode = debugMode; + } + + public boolean isDisplayPagesMenu() { + return displayPagesMenu; + } + + public void setDisplayPagesMenu(boolean displayPagesMenu) { + this.displayPagesMenu = displayPagesMenu; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/system/MerchantConfiguration.java b/sm-core-model/src/main/java/com/salesmanager/core/model/system/MerchantConfiguration.java new file mode 100755 index 0000000000..f61fb8bada --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/system/MerchantConfiguration.java @@ -0,0 +1,139 @@ +package com.salesmanager.core.model.system; + +import java.io.Serializable; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; +import org.hibernate.annotations.Type; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + +/** + * Merchant configuration information + * + * @author Carl Samson + * + */ +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "MERCHANT_CONFIGURATION", + uniqueConstraints = @UniqueConstraint(columnNames = {"MERCHANT_ID", "CONFIG_KEY"})) +public class MerchantConfiguration extends SalesManagerEntity + implements Serializable, Auditable { + + /** + * + */ + private static final long serialVersionUID = 4246917986731953459L; + + @Id + @Column(name = "MERCHANT_CONFIG_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", + valueColumnName = "SEQ_COUNT", pkColumnValue = "MERCH_CONF_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "MERCHANT_ID", nullable = true) + private MerchantStore merchantStore; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @Column(name = "CONFIG_KEY") + private String key; + + /** + * activate and deactivate configuration + */ + @Column(name = "ACTIVE", nullable = true) + private Boolean active = new Boolean(false); + + + @Column(name = "VALUE") + @Type(type = "org.hibernate.type.TextType") + private String value; + + @Column(name = "TYPE") + @Enumerated(value = EnumType.STRING) + private MerchantConfigurationType merchantConfigurationType = + MerchantConfigurationType.INTEGRATION; + + public void setKey(String key) { + this.key = key; + } + + public String getKey() { + return key; + } + + public void setValue(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public AuditSection getAuditSection() { + return auditSection; + } + + public void setAuditSection(AuditSection auditSection) { + this.auditSection = auditSection; + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public void setMerchantConfigurationType(MerchantConfigurationType merchantConfigurationType) { + this.merchantConfigurationType = merchantConfigurationType; + } + + public MerchantConfigurationType getMerchantConfigurationType() { + return merchantConfigurationType; + } + + public Boolean getActive() { + return active; + } + + public void setActive(Boolean active) { + this.active = active; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/system/MerchantConfigurationType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/system/MerchantConfigurationType.java new file mode 100755 index 0000000000..4067cfef71 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/system/MerchantConfigurationType.java @@ -0,0 +1,10 @@ +package com.salesmanager.core.model.system; + +public enum MerchantConfigurationType { + + INTEGRATION, + SHOP, + CONFIG, + SOCIAL + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/system/MerchantLog.java b/sm-core-model/src/main/java/com/salesmanager/core/model/system/MerchantLog.java new file mode 100755 index 0000000000..42fd0b10a8 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/system/MerchantLog.java @@ -0,0 +1,106 @@ +package com.salesmanager.core.model.system; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import org.hibernate.annotations.Type; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "MERCHANT_LOG") +public class MerchantLog extends SalesManagerEntity implements Serializable { + + + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "MERCHANT_LOG_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "MR_LOG_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore store; + + @Column(name="MODULE", length=25, nullable=true) + private String module; + + + @Column(name="LOG") + @Type(type = "org.hibernate.type.TextType") + private String log; + + public MerchantLog(MerchantStore store, String log) { + this.store = store; + this.log = log; + } + + public MerchantLog(MerchantStore store, String module, String log) { + this.store = store; + this.module = module; + this.log = log; + } + + + public Long getId() { + return id; + } + + + public void setId(Long id) { + this.id = id; + } + + + public MerchantStore getStore() { + return store; + } + + + public void setStore(MerchantStore store) { + this.store = store; + } + + + public String getModule() { + return module; + } + + + public void setModule(String module) { + this.module = module; + } + + + public String getLog() { + return log; + } + + + public void setLog(String log) { + this.log = log; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/system/Module.java b/sm-core-model/src/main/java/com/salesmanager/core/model/system/Module.java new file mode 100755 index 0000000000..6257794476 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/system/Module.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.system; + +public enum Module { + + PAYMENT, SHIPPING + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/system/ModuleConfig.java b/sm-core-model/src/main/java/com/salesmanager/core/model/system/ModuleConfig.java new file mode 100755 index 0000000000..283aa5c7ef --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/system/ModuleConfig.java @@ -0,0 +1,56 @@ +package com.salesmanager.core.model.system; + +public class ModuleConfig { + + + private String scheme; + private String host; + private String port; + private String uri; + private String env; + private String config1; + private String config2; + public String getScheme() { + return scheme; + } + public void setScheme(String scheme) { + this.scheme = scheme; + } + public String getHost() { + return host; + } + public void setHost(String host) { + this.host = host; + } + public String getPort() { + return port; + } + public void setPort(String port) { + this.port = port; + } + public String getUri() { + return uri; + } + public void setUri(String uri) { + this.uri = uri; + } + public void setEnv(String env) { + this.env = env; + } + public String getEnv() { + return env; + } + public String getConfig1() { + return config1; + } + public void setConfig1(String config1) { + this.config1 = config1; + } + public String getConfig2() { + return config2; + } + public void setConfig2(String config2) { + this.config2 = config2; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/system/SystemConfiguration.java b/sm-core-model/src/main/java/com/salesmanager/core/model/system/SystemConfiguration.java new file mode 100755 index 0000000000..5771123cc4 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/system/SystemConfiguration.java @@ -0,0 +1,80 @@ +package com.salesmanager.core.model.system; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; + +/** + * Global system configuration information + * @author casams1 + * + */ +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "SYSTEM_CONFIGURATION") +public class SystemConfiguration extends SalesManagerEntity implements Serializable, Auditable { + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "SYSTEM_CONFIG_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "SYST_CONF_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Column(name="CONFIG_KEY") + private String key; + + @Column(name="VALUE") + private String value; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + public AuditSection getAuditSection() { + return auditSection; + } + + public void setAuditSection(AuditSection auditSection) { + this.auditSection = auditSection; + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/system/SystemNotification.java b/sm-core-model/src/main/java/com/salesmanager/core/model/system/SystemNotification.java new file mode 100755 index 0000000000..7a0a632616 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/system/SystemNotification.java @@ -0,0 +1,138 @@ +package com.salesmanager.core.model.system; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.UniqueConstraint; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.user.User; + +@Entity +@EntityListeners(value = AuditListener.class) + +@Table(name = "SYSTEM_NOTIFICATION",uniqueConstraints= + @UniqueConstraint(columnNames = {"MERCHANT_ID", "CONFIG_KEY"}) ) +public class SystemNotification extends SalesManagerEntity implements Serializable, Auditable { + + /** + * + */ + private static final long serialVersionUID = -6269172313628887000L; + + @Id + @Column(name = "SYSTEM_NOTIF_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "SYST_NOTIF_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Column(name="CONFIG_KEY") + private String key; + + @Column(name="VALUE") + private String value; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=true) + private MerchantStore merchantStore; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="USER_ID", nullable=true) + private User user; + + @Temporal(TemporalType.DATE) + @Column(name = "START_DATE") + private Date startDate; + + @Temporal(TemporalType.DATE) + @Column(name = "END_DATE") + private Date endDate; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + public AuditSection getAuditSection() { + return auditSection; + } + + public void setAuditSection(AuditSection auditSection) { + this.auditSection = auditSection; + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getStartDate() { + return startDate; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setUser(User user) { + this.user = user; + } + + public User getUser() { + return user; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/system/credentials/Credentials.java b/sm-core-model/src/main/java/com/salesmanager/core/model/system/credentials/Credentials.java new file mode 100755 index 0000000000..a4af13d50f --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/system/credentials/Credentials.java @@ -0,0 +1,20 @@ +package com.salesmanager.core.model.system.credentials; + +public abstract class Credentials { + + private String userName; + private String password; + public String getUserName() { + return userName; + } + public void setUserName(String userName) { + this.userName = userName; + } + public String getPassword() { + return password; + } + public void setPassword(String password) { + this.password = password; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/system/credentials/DbCredentials.java b/sm-core-model/src/main/java/com/salesmanager/core/model/system/credentials/DbCredentials.java new file mode 100755 index 0000000000..d38ef79e6f --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/system/credentials/DbCredentials.java @@ -0,0 +1,5 @@ +package com.salesmanager.core.model.system.credentials; + +public class DbCredentials extends Credentials { + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/system/optin/CustomerOptin.java b/sm-core-model/src/main/java/com/salesmanager/core/model/system/optin/CustomerOptin.java new file mode 100755 index 0000000000..f95043a59e --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/system/optin/CustomerOptin.java @@ -0,0 +1,145 @@ +package com.salesmanager.core.model.system.optin; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.UniqueConstraint; + +import org.hibernate.annotations.Type; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + + +/** + * Optin defines optin campaigns for the system. + * @author carlsamson + * + */ +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "CUSTOMER_OPTIN",uniqueConstraints= +@UniqueConstraint(columnNames = {"EMAIL", "OPTIN_ID"})) +public class CustomerOptin extends SalesManagerEntity implements Serializable { + + + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "CUSTOMER_OPTIN_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "CUST_OPT_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Temporal(TemporalType.TIMESTAMP) + @Column (name ="OPTIN_DATE") + private Date optinDate; + + + @ManyToOne(targetEntity = Optin.class) + @JoinColumn(name="OPTIN_ID") + private Optin optin; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore merchantStore; + + @Column(name="FIRST") + private String firstName; + + @Column(name="LAST") + private String lastName; + + @Column(name="EMAIL", nullable=false) + private String email; + + @Column(name="VALUE") + @Type(type = "org.hibernate.type.TextType") + private String value; + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public Date getOptinDate() { + return optinDate; + } + + public void setOptinDate(Date optinDate) { + this.optinDate = optinDate; + } + + public Optin getOptin() { + return optin; + } + + public void setOptin(Optin optin) { + this.optin = optin; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/system/optin/Optin.java b/sm-core-model/src/main/java/com/salesmanager/core/model/system/optin/Optin.java new file mode 100755 index 0000000000..b5df8e7d0c --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/system/optin/Optin.java @@ -0,0 +1,133 @@ +package com.salesmanager.core.model.system.optin; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.UniqueConstraint; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; + + +/** + * Optin defines optin campaigns for the system. + * @author carlsamson + * + */ +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "OPTIN",uniqueConstraints= +@UniqueConstraint(columnNames = {"MERCHANT_ID", "CODE"})) +public class Optin extends SalesManagerEntity implements Serializable { + + + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "OPTIN_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "OPTIN_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Temporal(TemporalType.TIMESTAMP) + @Column (name ="START_DATE") + private Date startDate; + + @Temporal(TemporalType.TIMESTAMP) + @Column (name ="END_DATE") + private Date endDate; + + @Column(name="TYPE", nullable=false) + @Enumerated(value = EnumType.STRING) + private OptinType optinType; + + @ManyToOne(targetEntity = MerchantStore.class) + @JoinColumn(name="MERCHANT_ID") + private MerchantStore merchant; + + @Column(name="CODE", nullable=false) + private String code; + + @Column(name="DESCRIPTION") + private String description; + + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + public MerchantStore getMerchant() { + return merchant; + } + + public void setMerchant(MerchantStore merchant) { + this.merchant = merchant; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public OptinType getOptinType() { + return optinType; + } + + public void setOptinType(OptinType optinType) { + this.optinType = optinType; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/system/optin/OptinType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/system/optin/OptinType.java new file mode 100755 index 0000000000..1608d915d8 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/system/optin/OptinType.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.system.optin; + +public enum OptinType { + + NEWSLETTER, PROMOTIONS + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/tax/TaxBasisCalculation.java b/sm-core-model/src/main/java/com/salesmanager/core/model/tax/TaxBasisCalculation.java new file mode 100755 index 0000000000..3a86d2ff45 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/tax/TaxBasisCalculation.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.tax; + +public enum TaxBasisCalculation { + + STOREADDRESS, SHIPPINGADDRESS, BILLINGADDRESS + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/tax/TaxConfiguration.java b/sm-core-model/src/main/java/com/salesmanager/core/model/tax/TaxConfiguration.java new file mode 100755 index 0000000000..57edc3d2b5 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/tax/TaxConfiguration.java @@ -0,0 +1,53 @@ +package com.salesmanager.core.model.tax; + +import org.json.simple.JSONAware; +import org.json.simple.JSONObject; + +/** + * Set of various tax configuration settings saved in MerchantConfiguration + * @author carl samson + * + */ +public class TaxConfiguration implements JSONAware { + + private TaxBasisCalculation taxBasisCalculation = TaxBasisCalculation.SHIPPINGADDRESS; + + private boolean collectTaxIfDifferentProvinceOfStoreCountry = true; + private boolean collectTaxIfDifferentCountryOfStoreCountry = false; + + @SuppressWarnings("unchecked") + @Override + public String toJSONString() { + JSONObject data = new JSONObject(); + data.put("taxBasisCalculation", this.getTaxBasisCalculation().name()); + + return data.toJSONString(); + } + + public void setTaxBasisCalculation(TaxBasisCalculation taxBasisCalculation) { + this.taxBasisCalculation = taxBasisCalculation; + } + + public TaxBasisCalculation getTaxBasisCalculation() { + return taxBasisCalculation; + } + + public void setCollectTaxIfDifferentProvinceOfStoreCountry( + boolean collectTaxIfDifferentProvinceOfStoreCountry) { + this.collectTaxIfDifferentProvinceOfStoreCountry = collectTaxIfDifferentProvinceOfStoreCountry; + } + + public boolean isCollectTaxIfDifferentProvinceOfStoreCountry() { + return collectTaxIfDifferentProvinceOfStoreCountry; + } + + public void setCollectTaxIfDifferentCountryOfStoreCountry( + boolean collectTaxIfDifferentCountryOfStoreCountry) { + this.collectTaxIfDifferentCountryOfStoreCountry = collectTaxIfDifferentCountryOfStoreCountry; + } + + public boolean isCollectTaxIfDifferentCountryOfStoreCountry() { + return collectTaxIfDifferentCountryOfStoreCountry; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/tax/TaxItem.java b/sm-core-model/src/main/java/com/salesmanager/core/model/tax/TaxItem.java new file mode 100755 index 0000000000..50c9b5ba49 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/tax/TaxItem.java @@ -0,0 +1,32 @@ +package com.salesmanager.core.model.tax; + +import com.salesmanager.core.model.order.OrderTotalItem; +import com.salesmanager.core.model.tax.taxrate.TaxRate; + +public class TaxItem extends OrderTotalItem { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String label; + private TaxRate taxRate=null; + + public void setLabel(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } + + public void setTaxRate(TaxRate taxRate) { + this.taxRate = taxRate; + } + + public TaxRate getTaxRate() { + return taxRate; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/tax/taxclass/TaxClass.java b/sm-core-model/src/main/java/com/salesmanager/core/model/tax/taxclass/TaxClass.java new file mode 100755 index 0000000000..ce07873ef1 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/tax/taxclass/TaxClass.java @@ -0,0 +1,121 @@ +package com.salesmanager.core.model.tax.taxclass; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import javax.validation.constraints.NotEmpty; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.tax.taxrate.TaxRate; + +@Entity +@Table(name = "TAX_CLASS", +indexes = { @Index(name="TAX_CLASS_CODE_IDX",columnList = "TAX_CLASS_CODE")}, +uniqueConstraints= + @UniqueConstraint(columnNames = {"MERCHANT_ID", "TAX_CLASS_CODE"}) ) + + +public class TaxClass extends SalesManagerEntity { + private static final long serialVersionUID = 1L; + + public final static String DEFAULT_TAX_CLASS = "DEFAULT"; + + public TaxClass(String code) { + this.code = code; + this.title = code; + } + + @Id + @Column(name = "TAX_CLASS_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "TX_CLASS_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @NotEmpty + @Column(name="TAX_CLASS_CODE", nullable=false, length=10) + private String code; + + @NotEmpty + @Column(name = "TAX_CLASS_TITLE" , nullable=false , length=32 ) + private String title; + + + + @OneToMany(mappedBy = "taxClass", targetEntity = Product.class) + private List products = new ArrayList(); + + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=true) + private MerchantStore merchantStore; + + + @OneToMany(mappedBy = "taxClass") + private List taxRates = new ArrayList(); + + public TaxClass() { + super(); + } + + @Override + public Long getId() { + return this.id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public List getTaxRates() { + return taxRates; + } + + public void setTaxRates(List taxRates) { + this.taxRates = taxRates; + } + + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/tax/taxrate/TaxRate.java b/sm-core-model/src/main/java/com/salesmanager/core/model/tax/taxrate/TaxRate.java new file mode 100755 index 0000000000..47b8a68530 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/tax/taxrate/TaxRate.java @@ -0,0 +1,252 @@ +/* + * Licensed to csti consulting + * You may obtain a copy of the License at + * + * http://www.csticonsulting.com + * Copyright (c) 2006-Aug 24, 2010 Consultation CS-TI inc. + * + * 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 com.salesmanager.core.model.tax.taxrate; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; +import javax.validation.Valid; + +import javax.validation.constraints.NotEmpty; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.core.model.tax.taxclass.TaxClass; + +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "TAX_RATE" , uniqueConstraints={ + @UniqueConstraint(columnNames={ + "TAX_CODE", + "MERCHANT_ID" + }) + } + ) +public class TaxRate extends SalesManagerEntity implements Auditable { + private static final long serialVersionUID = 3356827741612925066L; + + @Id + @Column(name = "TAX_RATE_ID") + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "TAX_RATE_ID_NEXT_VALUE") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @Column(name = "TAX_PRIORITY") + private Integer taxPriority = 0; + + @Column(name = "TAX_RATE" , nullable= false , precision=7, scale=4) + private BigDecimal taxRate; + + @NotEmpty + @Column(name = "TAX_CODE") + private String code; + + + @Column(name = "PIGGYBACK") + private boolean piggyback; + + @ManyToOne + @JoinColumn(name = "TAX_CLASS_ID" , nullable=false) + private TaxClass taxClass; + + + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore merchantStore; + + @Valid + @OneToMany(mappedBy = "taxRate", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private List descriptions = new ArrayList(); + + @ManyToOne(fetch = FetchType.LAZY, targetEntity = Country.class) + @JoinColumn(name="COUNTRY_ID", nullable=false, updatable=true) + private Country country; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name="ZONE_ID", nullable=true, updatable=true) + private Zone zone; + + @Column(name = "STORE_STATE_PROV", length=100) + private String stateProvince; + + @ManyToOne + @JoinColumn(name = "PARENT_ID") + private TaxRate parent; + + @OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE, orphanRemoval = true) + private List taxRates = new ArrayList(); + + @Transient + private String rateText; + + + public String getRateText() { + return rateText; + } + + public void setRateText(String rateText) { + this.rateText = rateText; + } + + public TaxRate() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection auditSection) { + this.auditSection = auditSection; + } + + public Integer getTaxPriority() { + return taxPriority; + } + + public void setTaxPriority(Integer taxPriority) { + this.taxPriority = taxPriority; + } + + public BigDecimal getTaxRate() { + return taxRate; + } + + public void setTaxRate(BigDecimal taxRate) { + this.taxRate = taxRate; + } + + public boolean isPiggyback() { + return piggyback; + } + + public void setPiggyback(boolean piggyback) { + this.piggyback = piggyback; + } + + public TaxClass getTaxClass() { + return taxClass; + } + + public void setTaxClass(TaxClass taxClass) { + this.taxClass = taxClass; + } + + + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + + + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public void setCountry(Country country) { + this.country = country; + } + + public Country getCountry() { + return country; + } + + public void setZone(Zone zone) { + this.zone = zone; + } + + public Zone getZone() { + return zone; + } + + + public void setTaxRates(List taxRates) { + this.taxRates = taxRates; + } + + public List getTaxRates() { + return taxRates; + } + + public void setParent(TaxRate parent) { + this.parent = parent; + } + + public TaxRate getParent() { + return parent; + } + + public void setStateProvince(String stateProvince) { + this.stateProvince = stateProvince; + } + + public String getStateProvince() { + return stateProvince; + } + + public void setCode(String code) { + this.code = code; + } + + public String getCode() { + return code; + } +} \ No newline at end of file diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/tax/taxrate/TaxRateDescription.java b/sm-core-model/src/main/java/com/salesmanager/core/model/tax/taxrate/TaxRateDescription.java new file mode 100755 index 0000000000..37a8ce4d6c --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/tax/taxrate/TaxRateDescription.java @@ -0,0 +1,57 @@ +/* + * Licensed to csti consulting + * You may obtain a copy of the License at + * + * http://www.csticonsulting.com + * Copyright (c) 2006-Aug 24, 2010 Consultation CS-TI inc. + * + * 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 com.salesmanager.core.model.tax.taxrate; + +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.description.Description; + + +@Entity +@Table(name = "TAX_RATE_DESCRIPTION" ,uniqueConstraints={ + @UniqueConstraint(columnNames={ + "TAX_RATE_ID", + "LANGUAGE_ID" + }) + } +) + +@TableGenerator(name = "description_gen", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "taxrate_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_ALLOCATION_SIZE, initialValue = SchemaConstant.DESCRIPTION_ID_START_VALUE) +//@SequenceGenerator(name = "description_gen", sequenceName = "taxrate_description_seq", allocationSize = SchemaConstant.DESCRIPTION_ID_SEQUENCE_START) +public class TaxRateDescription extends Description { + private static final long serialVersionUID = 1L; + + @ManyToOne(targetEntity = TaxRate.class) + @JoinColumn(name = "TAX_RATE_ID") + private TaxRate taxRate; + + public TaxRateDescription() { + } + + public TaxRate getTaxRate() { + return taxRate; + } + + public void setTaxRate(TaxRate taxRate) { + this.taxRate = taxRate; + } +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/user/Group.java b/sm-core-model/src/main/java/com/salesmanager/core/model/user/Group.java new file mode 100755 index 0000000000..79115a535a --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/user/Group.java @@ -0,0 +1,120 @@ +package com.salesmanager.core.model.user; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.validation.constraints.NotEmpty; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; + +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "SM_GROUP", indexes = { + @Index(name = "SM_GROUP_GROUP_TYPE", columnList = "GROUP_TYPE") }) +public class Group extends SalesManagerEntity implements Auditable { + + /** + * + */ + private static final long serialVersionUID = 1L; + @Id + @Column(name = "GROUP_ID", unique = true, nullable = false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "GROUP_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Integer id; + + public Group() { + + } + + @Column(name = "GROUP_TYPE") + @Enumerated(value = EnumType.STRING) + private GroupType groupType; + + @NotEmpty + @Column(name = "GROUP_NAME", unique = true) + private String groupName; + + public Group(String groupName) { + this.groupName = groupName; + } + + @JsonIgnore + @ManyToMany(cascade = { + CascadeType.PERSIST, + CascadeType.MERGE + }) + @JoinTable(name = "PERMISSION_GROUP", + joinColumns = @JoinColumn(name = "GROUP_ID"), + inverseJoinColumns = @JoinColumn(name = "PERMISSION_ID") + ) + private Set permissions = new HashSet(); + + public Set getPermissions() { + return permissions; + } + + public void setPermissions(Set permissions) { + this.permissions = permissions; + } + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @Override + public AuditSection getAuditSection() { + return this.auditSection; + } + + @Override + public void setAuditSection(AuditSection audit) { + this.auditSection = audit; + } + + @Override + public Integer getId() { + return this.id; + } + + @Override + public void setId(Integer id) { + this.id = id; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public void setGroupType(GroupType groupType) { + this.groupType = groupType; + } + + public GroupType getGroupType() { + return groupType; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/user/GroupType.java b/sm-core-model/src/main/java/com/salesmanager/core/model/user/GroupType.java new file mode 100755 index 0000000000..2547133263 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/user/GroupType.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.model.user; + +public enum GroupType { + + ADMIN, CUSTOMER + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/user/Permission.java b/sm-core-model/src/main/java/com/salesmanager/core/model/user/Permission.java new file mode 100755 index 0000000000..23a13c1cea --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/user/Permission.java @@ -0,0 +1,97 @@ +package com.salesmanager.core.model.user; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.ManyToMany; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.validation.constraints.NotEmpty; + +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; + +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "PERMISSION") +public class Permission extends SalesManagerEntity implements Auditable { + + + + private static final long serialVersionUID = 813468140197420748L; + + @Id + @Column(name = "PERMISSION_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "PERMISSION_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Integer id; + + public Permission() { + + } + + public Permission(String permissionName) { + this.permissionName = permissionName; + } + + + @NotEmpty + @Column(name="PERMISSION_NAME", unique=true) + private String permissionName; + + @ManyToMany(mappedBy = "permissions") + private List groups = new ArrayList(); + + @Embedded + private AuditSection auditSection = new AuditSection(); + + + @Override + public Integer getId() { + return this.id; + } + + @Override + public void setId(Integer id) { + this.id = id; + + } + + @Override + public AuditSection getAuditSection() { + return this.auditSection; + } + + @Override + public void setAuditSection(AuditSection audit) { + this.auditSection = audit; + + } + + public String getPermissionName() { + return permissionName; + } + + public void setPermissionName(String permissionName) { + this.permissionName = permissionName; + } + + public void setGroups(List groups) { + this.groups = groups; + } + + public List getGroups() { + return groups; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/user/PermissionCriteria.java b/sm-core-model/src/main/java/com/salesmanager/core/model/user/PermissionCriteria.java new file mode 100755 index 0000000000..026c1e1706 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/user/PermissionCriteria.java @@ -0,0 +1,54 @@ +package com.salesmanager.core.model.user; + +import java.util.List; +import java.util.Set; + +import com.salesmanager.core.model.common.Criteria; + +public class PermissionCriteria extends Criteria { + + + private String permissionName; + + + private Boolean available = null; + + private Set groupIds; + + private List availabilities; + + + public List getAvailabilities() { + return availabilities; + } + + public void setAvailabilities(List availabilities) { + this.availabilities = availabilities; + } + + public Boolean getAvailable() { + return available; + } + + public void setAvailable(Boolean available) { + this.available = available; + } + + public String getPermissionName() { + return permissionName; + } + + public void setPermissionName(String permissionName) { + this.permissionName = permissionName; + } + + public Set getGroupIds() { + return groupIds; + } + + public void setGroupIds(Set groupIds) { + this.groupIds = groupIds; + } + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/user/PermissionList.java b/sm-core-model/src/main/java/com/salesmanager/core/model/user/PermissionList.java new file mode 100755 index 0000000000..6f670e31b8 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/user/PermissionList.java @@ -0,0 +1,26 @@ +package com.salesmanager.core.model.user; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class PermissionList implements Serializable { + + + private static final long serialVersionUID = -3122326940968441727L; + private int totalCount; + private List permissions = new ArrayList(); + public int getTotalCount() { + return totalCount; + } + public void setTotalCount(int totalCount) { + this.totalCount = totalCount; + } + public List getPermissions() { + return permissions; + } + public void setPermissions(List permissions) { + this.permissions = permissions; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/user/User.java b/sm-core-model/src/main/java/com/salesmanager/core/model/user/User.java new file mode 100755 index 0000000000..e7cb55601e --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/user/User.java @@ -0,0 +1,336 @@ +package com.salesmanager.core.model.user; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.UniqueConstraint; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotEmpty; + +import org.hibernate.annotations.Cascade; + +import com.salesmanager.core.model.common.CredentialsReset; +import com.salesmanager.core.model.common.audit.AuditListener; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; +import com.salesmanager.core.model.generic.SalesManagerEntity; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +/** + * User management + * @author carlsamson + * + */ +@Entity +@EntityListeners(value = AuditListener.class) +@Table(name = "USERS", + indexes = { @Index(name="USR_NAME_IDX", columnList = "ADMIN_NAME")}, + uniqueConstraints= + @UniqueConstraint(columnNames = {"MERCHANT_ID", "ADMIN_NAME"})) +public class User extends SalesManagerEntity implements Auditable { + + + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "USER_ID", unique=true, nullable=false) + @TableGenerator(name = "TABLE_GEN", table = "SM_SEQUENCER", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "USER_SEQ_NEXT_VAL") + @GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GEN") + private Long id; + + public User() { + + } + + public User(String userName,String password, String email) { + + this.adminName = userName; + this.adminPassword = password; + this.adminEmail = email; + } + + @NotEmpty + @Column(name="ADMIN_NAME", length=100) + private String adminName; + + @ManyToMany(fetch=FetchType.LAZY, cascade = {CascadeType.REFRESH}) + @JoinTable(name = "USER_GROUP", joinColumns = { + @JoinColumn(name = "USER_ID", nullable = false, updatable = false) } + , + inverseJoinColumns = { @JoinColumn(name = "GROUP_ID", + nullable = false, updatable = false) } + ) + @Cascade({ + org.hibernate.annotations.CascadeType.DETACH, + org.hibernate.annotations.CascadeType.LOCK, + org.hibernate.annotations.CascadeType.REFRESH, + org.hibernate.annotations.CascadeType.REPLICATE + + }) + private List groups = new ArrayList(); + + @NotEmpty + @Email + @Column(name="ADMIN_EMAIL") + private String adminEmail; + + @NotEmpty + @Column(name="ADMIN_PASSWORD", length=60) + private String adminPassword; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="MERCHANT_ID", nullable=false) + private MerchantStore merchantStore; + + + @Column(name="ADMIN_FIRST_NAME") + private String firstName; + + @Column(name="ACTIVE") + private boolean active = true; + + + @Column(name="ADMIN_LAST_NAME") + private String lastName; + + @ManyToOne(fetch = FetchType.LAZY, targetEntity = Language.class) + @JoinColumn(name = "LANGUAGE_ID") + private Language defaultLanguage; + + + @Column(name="ADMIN_Q1") + private String question1; + + @Column(name="ADMIN_Q2") + private String question2; + + @Column(name="ADMIN_Q3") + private String question3; + + @Column(name="ADMIN_A1") + private String answer1; + + @Column(name="ADMIN_A2") + private String answer2; + + @Column(name="ADMIN_A3") + private String answer3; + + @Embedded + private AuditSection auditSection = new AuditSection(); + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "LAST_ACCESS") + private Date lastAccess; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "LOGIN_ACCESS") + private Date loginTime; + + @Embedded + private CredentialsReset credentialsResetRequest = null; + + + public CredentialsReset getCredentialsResetRequest() { + return credentialsResetRequest; + } + + public void setCredentialsResetRequest(CredentialsReset credentialsResetRequest) { + this.credentialsResetRequest = credentialsResetRequest; + } + + @Override + public Long getId() { + return this.id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + @Override + public AuditSection getAuditSection() { + return auditSection; + } + + @Override + public void setAuditSection(AuditSection audit) { + auditSection = audit; + + } + + public String getAdminName() { + return adminName; + } + + public void setAdminName(String adminName) { + this.adminName = adminName; + } + + public String getAdminEmail() { + return adminEmail; + } + + public void setAdminEmail(String adminEmail) { + this.adminEmail = adminEmail; + } + + public String getAdminPassword() { + return adminPassword; + } + + public void setAdminPassword(String adminPassword) { + this.adminPassword = adminPassword; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public Language getDefaultLanguage() { + return defaultLanguage; + } + + public void setDefaultLanguage(Language defaultLanguage) { + this.defaultLanguage = defaultLanguage; + } + + public String getQuestion1() { + return question1; + } + + public void setQuestion1(String question1) { + this.question1 = question1; + } + + public String getQuestion2() { + return question2; + } + + public void setQuestion2(String question2) { + this.question2 = question2; + } + + public String getQuestion3() { + return question3; + } + + public void setQuestion3(String question3) { + this.question3 = question3; + } + + public String getAnswer1() { + return answer1; + } + + public void setAnswer1(String answer1) { + this.answer1 = answer1; + } + + public String getAnswer2() { + return answer2; + } + + public void setAnswer2(String answer2) { + this.answer2 = answer2; + } + + public String getAnswer3() { + return answer3; + } + + public void setAnswer3(String answer3) { + this.answer3 = answer3; + } + + public void setGroups(List groups) { + this.groups = groups; + } + + public List getGroups() { + return groups; + } + + public MerchantStore getMerchantStore() { + return merchantStore; + } + + public void setMerchantStore(MerchantStore merchantStore) { + this.merchantStore = merchantStore; + } + + public void setActive(boolean active) { + this.active = active; + } + + public boolean isActive() { + return active; + } + + public void setLastAccess(Date lastAccess) { + this.lastAccess = lastAccess; + } + + public Date getLastAccess() { + return lastAccess; + } + + public void setLoginTime(Date loginTime) { + this.loginTime = loginTime; + } + + public Date getLoginTime() { + return loginTime; + } + +/* public String getResetPasswordToken() { + return resetPasswordToken; + } + + public void setResetPasswordToken(String resetPasswordToken) { + this.resetPasswordToken = resetPasswordToken; + } + + public Date getTokenPasswordExpiration() { + return tokenPasswordExpiration; + } + + public void setTokenPasswordExpiration(Date tokenPasswordExpiration) { + this.tokenPasswordExpiration = tokenPasswordExpiration; + }*/ + + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/model/user/UserCriteria.java b/sm-core-model/src/main/java/com/salesmanager/core/model/user/UserCriteria.java new file mode 100644 index 0000000000..7a46342d21 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/model/user/UserCriteria.java @@ -0,0 +1,29 @@ +package com.salesmanager.core.model.user; + +import com.salesmanager.core.model.common.Criteria; + +public class UserCriteria extends Criteria { + + private String adminEmail; + private String adminName; + private boolean active = true; + public String getAdminEmail() { + return adminEmail; + } + public void setAdminEmail(String adminEmail) { + this.adminEmail = adminEmail; + } + public boolean isActive() { + return active; + } + public void setActive(boolean active) { + this.active = active; + } + public String getAdminName() { + return adminName; + } + public void setAdminName(String adminName) { + this.adminName = adminName; + } + +} diff --git a/sm-core-model/src/main/java/com/salesmanager/core/utils/CloneUtils.java b/sm-core-model/src/main/java/com/salesmanager/core/utils/CloneUtils.java new file mode 100755 index 0000000000..6377078aa2 --- /dev/null +++ b/sm-core-model/src/main/java/com/salesmanager/core/utils/CloneUtils.java @@ -0,0 +1,16 @@ +package com.salesmanager.core.utils; + +import java.util.Date; + +public class CloneUtils { + + private CloneUtils() {}; + + public static Date clone(Date date) { + if (date != null) { + return (Date) date.clone(); + } + return null; + } + +} diff --git a/sm-core-modules/.gitignore b/sm-core-modules/.gitignore new file mode 100755 index 0000000000..b83d22266a --- /dev/null +++ b/sm-core-modules/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/sm-core-modules/.mvn/wrapper/MavenWrapperDownloader.java b/sm-core-modules/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100755 index 0000000000..fa4f7b499f --- /dev/null +++ b/sm-core-modules/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,110 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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 + + http://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. +*/ + +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = + "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: : " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/sm-core-modules/.mvn/wrapper/maven-wrapper.properties b/sm-core-modules/.mvn/wrapper/maven-wrapper.properties new file mode 100755 index 0000000000..a5fcc11920 --- /dev/null +++ b/sm-core-modules/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip \ No newline at end of file diff --git a/sm-core-modules/mvnw b/sm-core-modules/mvnw new file mode 100755 index 0000000000..5551fde8e7 --- /dev/null +++ b/sm-core-modules/mvnw @@ -0,0 +1,286 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + wget "$jarUrl" -O "$wrapperJarPath" + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + curl -o "$wrapperJarPath" "$jarUrl" + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/sm-core-modules/mvnw.cmd b/sm-core-modules/mvnw.cmd new file mode 100755 index 0000000000..48363fa60b --- /dev/null +++ b/sm-core-modules/mvnw.cmd @@ -0,0 +1,161 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" +FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + echo Found %WRAPPER_JAR% +) else ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" + echo Finished downloading %WRAPPER_JAR% +) +@REM End of extension + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/sm-core-modules/pom.xml b/sm-core-modules/pom.xml new file mode 100755 index 0000000000..e1e1a22b18 --- /dev/null +++ b/sm-core-modules/pom.xml @@ -0,0 +1,137 @@ + + + 4.0.0 + + + + com.shopizer + shopizer + 3.2.5 + + + + sm-core-modules + sm-core-modules + sm-core-modules is used for create new external modules implementation deployed in + maven. + + jar + http://www.shopizer.com + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + scm:git:git://github.com:shopizer-ecommerce/shopizer-sm-core-modules.git + + scm:git:ssh://github.com:shopizer-ecommerce/shopizer-sm-core-modules.git + + https://github.com/shopizer-ecommerce/shopizer-sm-core-modules + + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + + + + + + Shopizer Team + team@shopizer.com + Shopizer + http://www.shopizer.com + + + + + + com.shopizer + sm-core-model + + + + + + + + + + diff --git a/sm-core-modules/src/main/java/com/salesmanager/core/modules/Module.java b/sm-core-modules/src/main/java/com/salesmanager/core/modules/Module.java new file mode 100755 index 0000000000..079f7a6e24 --- /dev/null +++ b/sm-core-modules/src/main/java/com/salesmanager/core/modules/Module.java @@ -0,0 +1,15 @@ +package com.salesmanager.core.modules; + +/** + * Root interface for all modules + * @author carlsamson + * + */ +public interface Module { + + String getName(); + void setName(String name); + String getCode(); + void setCode(String code); + +} diff --git a/sm-core-modules/src/main/java/com/salesmanager/core/modules/constants/Constants.java b/sm-core-modules/src/main/java/com/salesmanager/core/modules/constants/Constants.java new file mode 100755 index 0000000000..db477a20dd --- /dev/null +++ b/sm-core-modules/src/main/java/com/salesmanager/core/modules/constants/Constants.java @@ -0,0 +1,7 @@ +package com.salesmanager.core.modules.constants; + +public class Constants { + + public final static String DISTANCE_KEY = "DISTANCE_KEY"; + +} diff --git a/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/IntegrationException.java b/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/IntegrationException.java new file mode 100755 index 0000000000..5d5e157905 --- /dev/null +++ b/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/IntegrationException.java @@ -0,0 +1,61 @@ +package com.salesmanager.core.modules.integration; + +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; + +public class IntegrationException extends ServiceException { + + + /** + * + */ + private static final long serialVersionUID = 1L; + + public static final int ERROR_VALIDATION_SAVE = 100; + public static final int TRANSACTION_EXCEPTION = 99; + + private List errorFields; + + private int errorCode = 0; + + public int getErrorCode() { + return errorCode; + } + + public void setErrorCode(int errorCode) { + this.errorCode = errorCode; + } + + public IntegrationException(Exception e) { + super(e); + } + + public IntegrationException(String message, Exception e) { + super(message,e); + } + + public IntegrationException(int code, String message) { + + super(message); + this.errorCode = code; + } + + public IntegrationException(int code) { + + this.errorCode = code; + } + + public IntegrationException(String message) { + super(message); + } + + public void setErrorFields(List errorFields) { + this.errorFields = errorFields; + } + + public List getErrorFields() { + return errorFields; + } + +} diff --git a/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/payment/model/PaymentModule.java b/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/payment/model/PaymentModule.java new file mode 100755 index 0000000000..ecb3832541 --- /dev/null +++ b/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/payment/model/PaymentModule.java @@ -0,0 +1,54 @@ +package com.salesmanager.core.modules.integration.payment.model; + +import java.math.BigDecimal; +import java.util.List; + +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.payments.Payment; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.modules.integration.IntegrationException; + +public interface PaymentModule { + + public void validateModuleConfiguration(IntegrationConfiguration integrationConfiguration, MerchantStore store) throws IntegrationException; + + + /** + * Returns token-value related to the initialization of the transaction This + * method is invoked for paypal express checkout + * @param store MerchantStore + * @param customer Customer + * @param amount BigDecimal + * @param payment Payment + * @param configuration IntegrationConfiguration + * @param module IntegrationModule + * @return Transaction a Transaction + * @throws IntegrationException IntegrationException + */ + public Transaction initTransaction( + MerchantStore store, Customer customer, BigDecimal amount, Payment payment, IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException; + + public Transaction authorize( + MerchantStore store, Customer customer, List items, BigDecimal amount, Payment payment, IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException; + + + public Transaction capture( + MerchantStore store, Customer customer, Order order, Transaction capturableTransaction, IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException; + + public Transaction authorizeAndCapture( + MerchantStore store, Customer customer, List items, BigDecimal amount, Payment payment, IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException; + + public Transaction refund( + boolean partial, MerchantStore store, Transaction transaction, Order order, BigDecimal amount, IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException; + +} diff --git a/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/CustomShippingQuoteItem.java b/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/CustomShippingQuoteItem.java new file mode 100755 index 0000000000..5f5e5a7fed --- /dev/null +++ b/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/CustomShippingQuoteItem.java @@ -0,0 +1,22 @@ +package com.salesmanager.core.modules.integration.shipping.model; + +import java.math.BigDecimal; + +public abstract class CustomShippingQuoteItem { + + private String priceText; + private BigDecimal price; + public void setPriceText(String priceText) { + this.priceText = priceText; + } + public String getPriceText() { + return priceText; + } + public void setPrice(BigDecimal price) { + this.price = price; + } + public BigDecimal getPrice() { + return price; + } + +} diff --git a/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/CustomShippingQuoteWeightItem.java b/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/CustomShippingQuoteWeightItem.java new file mode 100755 index 0000000000..d9f0bf91af --- /dev/null +++ b/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/CustomShippingQuoteWeightItem.java @@ -0,0 +1,39 @@ +package com.salesmanager.core.modules.integration.shipping.model; + +import org.json.simple.JSONAware; +import org.json.simple.JSONObject; + +public class CustomShippingQuoteWeightItem extends CustomShippingQuoteItem implements JSONAware { + + private int maximumWeight; + + private String priceText; + + public String getPriceText() { + return priceText; + } + + public void setPriceText(String priceText) { + this.priceText = priceText; + } + + public void setMaximumWeight(int maximumWeight) { + this.maximumWeight = maximumWeight; + } + + public int getMaximumWeight() { + return maximumWeight; + } + + @SuppressWarnings("unchecked") + public String toJSONString() { + JSONObject data = new JSONObject(); + data.put("price", super.getPrice()); + data.put("maximumWeight", this.getMaximumWeight()); + + return data.toJSONString(); + } + + + +} diff --git a/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/CustomShippingQuotesConfiguration.java b/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/CustomShippingQuotesConfiguration.java new file mode 100755 index 0000000000..3b9b4b2236 --- /dev/null +++ b/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/CustomShippingQuotesConfiguration.java @@ -0,0 +1,85 @@ +package com.salesmanager.core.modules.integration.shipping.model; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.core.model.system.CustomIntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationConfiguration; + +public class CustomShippingQuotesConfiguration extends IntegrationConfiguration implements CustomIntegrationConfiguration, Serializable { + + /** + * + */ + private String moduleCode; + + private List regions = new ArrayList(); + + + private static final long serialVersionUID = 1L; + + + @SuppressWarnings("unchecked") + public String toJSONString() { + //JSONObject data = new JSONObject(); + + //data.put("active", super.isActive()); + //data.put("moduleCode", this.getModuleCode()); + + + StringBuilder returnString = new StringBuilder(); + returnString.append("{"); + returnString.append("\"moduleCode\"").append(":\"").append(this.getModuleCode()).append("\""); + returnString.append(","); + returnString.append("\"active\"").append(":").append(this.isActive()); + + + + if(regions!=null && regions.size()>0) { + + returnString.append(","); + //org.json.simple.JSONArray array=new org.json.simple.JSONArray(); + StringBuilder regionsList = new StringBuilder(); + int countRegion = 0; + regionsList.append("["); + for(CustomShippingQuotesRegion region : regions) { + regionsList.append(region.toJSONString()); + countRegion ++; + if(countRegion regions) { + this.regions = regions; + } + + public List getRegions() { + return regions; + } + +} diff --git a/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/CustomShippingQuotesRegion.java b/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/CustomShippingQuotesRegion.java new file mode 100755 index 0000000000..2000797d24 --- /dev/null +++ b/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/CustomShippingQuotesRegion.java @@ -0,0 +1,88 @@ +package com.salesmanager.core.modules.integration.shipping.model; + +import java.util.List; + +import org.json.simple.JSONAware; + +public class CustomShippingQuotesRegion implements JSONAware { + + private String customRegionName;//a name given by the merchant for this custom region + private List countries;//a list of country code for this region + + private List quoteItems;//price max weight + + public void setQuoteItems(List quoteItems) { + this.quoteItems = quoteItems; + } + + public List getQuoteItems() { + return quoteItems; + } + + public void setCountries(List countries) { + this.countries = countries; + } + + public List getCountries() { + return countries; + } + + public void setCustomRegionName(String customRegionName) { + this.customRegionName = customRegionName; + } + + public String getCustomRegionName() { + return customRegionName; + } + + + public String toJSONString() { + + + StringBuilder returnString = new StringBuilder(); + returnString.append("{"); + returnString.append("\"customRegionName\"").append(":\"").append(this.getCustomRegionName()).append("\""); + + + + if(countries!=null) { + returnString.append(","); + StringBuilder coutriesList = new StringBuilder(); + int countCountry = 0; + coutriesList.append("["); + for(String country : countries) { + coutriesList.append("\"").append(country).append("\""); + countCountry ++; + if(countCountry getBoxPackagesDetails( + List products, MerchantStore store) throws ServiceException; + + public List getItemPackagesDetails( + List products, MerchantStore store) throws ServiceException; + +} diff --git a/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/ShippingQuoteModule.java b/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/ShippingQuoteModule.java new file mode 100755 index 0000000000..aa59c3c6aa --- /dev/null +++ b/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/ShippingQuoteModule.java @@ -0,0 +1,26 @@ +package com.salesmanager.core.modules.integration.shipping.model; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.shipping.PackageDetails; +import com.salesmanager.core.model.shipping.ShippingConfiguration; +import com.salesmanager.core.model.shipping.ShippingOption; +import com.salesmanager.core.model.shipping.ShippingOrigin; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.model.system.CustomIntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.modules.integration.IntegrationException; + +public interface ShippingQuoteModule { + + public void validateModuleConfiguration(IntegrationConfiguration integrationConfiguration, MerchantStore store) throws IntegrationException; + public CustomIntegrationConfiguration getCustomModuleConfiguration(MerchantStore store) throws IntegrationException; + + public List getShippingQuotes(ShippingQuote quote, List packages, BigDecimal orderTotal, Delivery delivery, ShippingOrigin origin, MerchantStore store, IntegrationConfiguration configuration, IntegrationModule module, ShippingConfiguration shippingConfiguration, Locale locale) throws IntegrationException; + +} diff --git a/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/ShippingQuotePrePostProcessModule.java b/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/ShippingQuotePrePostProcessModule.java new file mode 100755 index 0000000000..58f615d0ba --- /dev/null +++ b/sm-core-modules/src/main/java/com/salesmanager/core/modules/integration/shipping/model/ShippingQuotePrePostProcessModule.java @@ -0,0 +1,41 @@ +package com.salesmanager.core.modules.integration.shipping.model; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.shipping.PackageDetails; +import com.salesmanager.core.model.shipping.ShippingConfiguration; +import com.salesmanager.core.model.shipping.ShippingOrigin; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.modules.integration.IntegrationException; + +/** + * Invoked before or after quote processing + * @author carlsamson + * + */ +public interface ShippingQuotePrePostProcessModule { + + + public String getModuleCode(); + + + public void prePostProcessShippingQuotes( + ShippingQuote quote, + List packages, + BigDecimal orderTotal, + Delivery delivery, + ShippingOrigin origin, + MerchantStore store, + IntegrationConfiguration globalShippingConfiguration, + IntegrationModule currentModule, + ShippingConfiguration shippingConfiguration, + List allModules, + Locale locale) throws IntegrationException; + +} diff --git a/sm-core-modules/src/main/java/com/salesmanager/core/modules/order/total/OrderTotalPostProcessorModule.java b/sm-core-modules/src/main/java/com/salesmanager/core/modules/order/total/OrderTotalPostProcessorModule.java new file mode 100755 index 0000000000..8f0deb5cfe --- /dev/null +++ b/sm-core-modules/src/main/java/com/salesmanager/core/modules/order/total/OrderTotalPostProcessorModule.java @@ -0,0 +1,34 @@ +package com.salesmanager.core.modules.order.total; + + + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.OrderSummary; +import com.salesmanager.core.model.order.OrderTotal; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.modules.Module; + +/** + * Calculates order total based on specific + * modules implementation + * @author carlsamson + * + */ +public interface OrderTotalPostProcessorModule extends Module { + + /** + * Uses the OrderSummary and external tools for applying if necessary + * variations on the OrderTotal calculation. + * @param summary OrderSummary + * @param shoppingCartItem ShoppingCartItem + * @param product Product + * @param customer Customer + * @param store MerchantStore + * @return OrderTotal OrderTotal + * @throws Exception Exception + */ + OrderTotal caculateProductPiceVariation(final OrderSummary summary, final ShoppingCartItem shoppingCartItem, final Product product, final Customer customer, final MerchantStore store) throws Exception; + +} diff --git a/sm-core-modules/src/main/java/com/salesmanager/core/modules/utils/Encryption.java b/sm-core-modules/src/main/java/com/salesmanager/core/modules/utils/Encryption.java new file mode 100755 index 0000000000..585979612f --- /dev/null +++ b/sm-core-modules/src/main/java/com/salesmanager/core/modules/utils/Encryption.java @@ -0,0 +1,28 @@ +package com.salesmanager.core.modules.utils; + +/** + * Can be used to encrypt block or information that has to + * be maintained secret + * @author Carl Samson + * + */ +public interface Encryption { + + + /** + * Encrypts a string value + * @param value VALUE + * @return String encrypted string + * @throws Exception cannot encrypt + */ + public String encrypt(String value) throws Exception; + + /** + * Decrypts a string value + * @param value VLUE + * @return String encrypted string + * @throws Exception cannot encrypt + */ + public String decrypt(String value) throws Exception; + +} diff --git a/sm-core-modules/src/main/java/com/salesmanager/core/modules/utils/GeoLocation.java b/sm-core-modules/src/main/java/com/salesmanager/core/modules/utils/GeoLocation.java new file mode 100755 index 0000000000..31b0326eb1 --- /dev/null +++ b/sm-core-modules/src/main/java/com/salesmanager/core/modules/utils/GeoLocation.java @@ -0,0 +1,9 @@ +package com.salesmanager.core.modules.utils; + +import com.salesmanager.core.model.common.Address; + +public interface GeoLocation { + + Address getAddress(String ipAddress) throws Exception; + +} diff --git a/sm-core/.gitignore b/sm-core/.gitignore new file mode 100755 index 0000000000..955955cd70 --- /dev/null +++ b/sm-core/.gitignore @@ -0,0 +1,4 @@ +/SALESMANAGER-TEST.h2.db +/SALESMANAGER-TEST.trace.db +/target/ +/files/ diff --git a/sm-core/.mvn/wrapper/MavenWrapperDownloader.java b/sm-core/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100755 index 0000000000..fa4f7b499f --- /dev/null +++ b/sm-core/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,110 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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 + + http://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. +*/ + +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = + "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: : " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/sm-core/.mvn/wrapper/maven-wrapper.properties b/sm-core/.mvn/wrapper/maven-wrapper.properties new file mode 100755 index 0000000000..a5fcc11920 --- /dev/null +++ b/sm-core/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip \ No newline at end of file diff --git a/sm-core/mvnw b/sm-core/mvnw new file mode 100755 index 0000000000..5551fde8e7 --- /dev/null +++ b/sm-core/mvnw @@ -0,0 +1,286 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + wget "$jarUrl" -O "$wrapperJarPath" + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + curl -o "$wrapperJarPath" "$jarUrl" + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/sm-core/mvnw.cmd b/sm-core/mvnw.cmd new file mode 100755 index 0000000000..48363fa60b --- /dev/null +++ b/sm-core/mvnw.cmd @@ -0,0 +1,161 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" +FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + echo Found %WRAPPER_JAR% +) else ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" + echo Finished downloading %WRAPPER_JAR% +) +@REM End of extension + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/sm-core/pom.xml b/sm-core/pom.xml new file mode 100755 index 0000000000..a620e6a63a --- /dev/null +++ b/sm-core/pom.xml @@ -0,0 +1,245 @@ + + + 4.0.0 + + + com.shopizer + shopizer + 3.2.5 + + + sm-core + jar + + sm-core + http://www.shopizer.com + + + .00 + .00 + 0.1.6 + + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + + org.hibernate + hibernate-ehcache + + + + + com.shopizer + sm-core-model + + + + + com.shopizer + sm-core-modules + + + + + com.shopizer + shipping-canadapost-spring-boot-starter + 2.17.0 + + + + com.shopizer + shopizer-commons + 1.0.6 + + + + + + com.shopizer + shopizer-search-opensearch-spring-boot-starter + 1.0.3 + + + + + + + + + com.google.maps + google-maps-services + + + + org.kie + kie-ci + + + com.google.guava + guava + + + javax.annotation + jsr250-api + + + + + + org.drools + drools-decisiontables + + + + org.drools + drools-core + + + + org.drools + drools-compiler + + + + + org.kie + kie-spring + + + + + + org.infinispan + infinispan-core + + + + org.infinispan + infinispan-tree + + + + + org.apache.commons + commons-collections4 + + + + + commons-validator + commons-validator + + + commons-collections + commons-collections + + + + + + + org.freemarker + freemarker + + + + + org.springframework + spring-context-support + + + + + org.apache.httpcomponents + httpclient + + + + + com.amazonaws + aws-java-sdk-s3 + + + + + com.amazonaws + aws-java-sdk-ses + + + + + com.google.cloud + google-cloud-storage + + + com.google.guava + guava + + + + + + + + + com.paypal.sdk + merchantsdk + + + + + com.stripe + stripe-java + + + + + com.braintreepayments.gateway + braintree-java + + + + + + com.maxmind.geoip2 + geoip2 + + + + + + + com.google.guava + guava + + + + + + org.springframework.boot + spring-boot-starter-test + + + + com.h2database + h2 + + + + + + diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/ApplicationSearchConfiguration.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/ApplicationSearchConfiguration.java new file mode 100644 index 0000000000..4bdb07e638 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/ApplicationSearchConfiguration.java @@ -0,0 +1,54 @@ +package com.salesmanager.core.business.configuration; + +import java.util.List; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + +import modules.commons.search.configuration.Credentials; +import modules.commons.search.configuration.SearchHost; + +/** + * Reads search related properties required for search starter + * @author carlsamson + * + */ + + +@Configuration +@ConfigurationProperties(prefix = "search") +@PropertySource("classpath:shopizer-core.properties") +public class ApplicationSearchConfiguration { + + private String clusterName; + private Credentials credentials; + private List host; + private List searchLanguages; + public String getClusterName() { + return clusterName; + } + public void setClusterName(String clusterName) { + this.clusterName = clusterName; + } + public Credentials getCredentials() { + return credentials; + } + public void setCredentials(Credentials credentials) { + this.credentials = credentials; + } + public List getHost() { + return host; + } + public void setHost(List host) { + this.host = host; + } + public List getSearchLanguages() { + return searchLanguages; + } + public void setSearchLanguages(List searchLanguages) { + this.searchLanguages = searchLanguages; + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/CoreApplicationConfiguration.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/CoreApplicationConfiguration.java new file mode 100755 index 0000000000..870d649981 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/CoreApplicationConfiguration.java @@ -0,0 +1,24 @@ +package com.salesmanager.core.business.configuration; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration +@ComponentScan({"com.salesmanager.core.business"}) +@EnableAutoConfiguration +@EnableConfigurationProperties(ApplicationSearchConfiguration.class) +@EnableJpaRepositories(basePackages = "com.salesmanager.core.business.repositories") +@EntityScan(basePackages = "com.salesmanager.core.model") +@EnableTransactionManagement +@ImportResource("classpath:/spring/shopizer-core-context.xml") +public class CoreApplicationConfiguration { + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/DataConfiguration.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/DataConfiguration.java new file mode 100644 index 0000000000..4b18c23b51 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/DataConfiguration.java @@ -0,0 +1,126 @@ +package com.salesmanager.core.business.configuration; + +import java.util.Properties; + +import javax.persistence.EntityManagerFactory; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.transaction.PlatformTransactionManager; + +import com.zaxxer.hikari.HikariDataSource; + + +@Configuration +@EnableCaching +public class DataConfiguration { + + /** + * Datasource + */ + @Value("${db.driverClass}") + private String driverClassName; + + @Value("${db.jdbcUrl}") + private String url; + + @Value("${db.user}") + private String user; + + @Value("${db.password}") + private String password; + + + /** + * Other connection properties + */ + + @Value("${hibernate.hbm2ddl.auto}") + private String hbm2ddl; + + @Value("${hibernate.dialect}") + private String dialect; + + @Value("${db.show.sql}") + private String showSql; + + @Value("${db.preferredTestQuery}") + private String preferredTestQuery; + + @Value("${db.schema}") + private String schema; + + @Value("${db.preferredTestQuery}") + private String testQuery; + + @Value("${db.minPoolSize}") + private int minPoolSize; + + @Value("${db.maxPoolSize}") + private int maxPoolSize; + + @Bean + public HikariDataSource dataSource() { + HikariDataSource dataSource = DataSourceBuilder.create().type(HikariDataSource.class) + .driverClassName(driverClassName) + .url(url) + .username(user) + .password(password) + .build(); + + /** Datasource config **/ + dataSource.setIdleTimeout(minPoolSize); + dataSource.setMaximumPoolSize(maxPoolSize); + dataSource.setConnectionTestQuery(testQuery); + + return dataSource; + } + + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory() { + + HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + vendorAdapter.setGenerateDdl(true); + + LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); + factory.setJpaVendorAdapter(vendorAdapter); + factory.setPackagesToScan("com.salesmanager.core.model"); + factory.setJpaProperties(additionalProperties()); + factory.setDataSource(dataSource()); + return factory; + } + + final Properties additionalProperties() { + final Properties hibernateProperties = new Properties(); + + hibernateProperties.setProperty("hibernate.hbm2ddl.auto", hbm2ddl); + hibernateProperties.setProperty("hibernate.default_schema", schema); + hibernateProperties.setProperty("hibernate.dialect", dialect); + hibernateProperties.setProperty("hibernate.show_sql", showSql); + hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", "true"); + hibernateProperties.setProperty("hibernate.cache.use_query_cache", "true"); + hibernateProperties.setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory"); + hibernateProperties.setProperty("hibernate.connection.CharSet", "utf8"); + hibernateProperties.setProperty("hibernate.connection.characterEncoding", "utf8"); + hibernateProperties.setProperty("hibernate.connection.useUnicode", "true"); + hibernateProperties.setProperty("hibernate.id.new_generator_mappings", "false"); //unless you run on a new schema + hibernateProperties.setProperty("hibernate.generate_statistics", "false"); + // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true"); + return hibernateProperties; + } + + @Bean + public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { + + JpaTransactionManager txManager = new JpaTransactionManager(); + txManager.setEntityManagerFactory(entityManagerFactory); + return txManager; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/DroolsBeanFactory.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/DroolsBeanFactory.java new file mode 100644 index 0000000000..93b60b1249 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/DroolsBeanFactory.java @@ -0,0 +1,112 @@ +package com.salesmanager.core.business.configuration; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import org.drools.decisiontable.DecisionTableProviderImpl; +import org.kie.api.KieServices; +import org.kie.api.builder.KieBuilder; +import org.kie.api.builder.KieFileSystem; +import org.kie.api.builder.KieModule; +import org.kie.api.builder.KieRepository; +import org.kie.api.builder.ReleaseId; +import org.kie.api.io.Resource; +import org.kie.api.runtime.KieContainer; +import org.kie.api.runtime.KieSession; +import org.kie.internal.builder.DecisionTableConfiguration; +import org.kie.internal.builder.DecisionTableInputType; +import org.kie.internal.builder.KnowledgeBuilderFactory; +import org.kie.internal.io.ResourceFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class DroolsBeanFactory { + + + @Value("${config.shipping.rule.priceByDistance}") + private String priceByDistance; + + @Value("${config.shipping.rule.shippingModuleDecision}") + private String shippingDecision; + + + private static final String RULES_PATH = "com/salesmanager/drools/rules/"; + private KieServices kieServices = KieServices.Factory.get(); + + private KieFileSystem getKieFileSystem() throws IOException{ + KieFileSystem kieFileSystem = kieServices.newKieFileSystem(); + List rules=Arrays.asList(priceByDistance,shippingDecision); + for(String rule:rules){ + kieFileSystem.write(ResourceFactory.newClassPathResource(rule)); + } + return kieFileSystem; + } + + public KieContainer getKieContainer() throws IOException { + getKieRepository(); + + KieBuilder kb = kieServices.newKieBuilder(getKieFileSystem()); + kb.buildAll(); + + KieModule kieModule = kb.getKieModule(); + + return kieServices.newKieContainer(kieModule.getReleaseId()); + + } + + private void getKieRepository() { + final KieRepository kieRepository = kieServices.getRepository(); + kieRepository.addKieModule(kieRepository::getDefaultReleaseId); + } + + public KieSession getKieSession(){ + getKieRepository(); + KieFileSystem kieFileSystem = kieServices.newKieFileSystem(); + + kieFileSystem.write(ResourceFactory.newClassPathResource(RULES_PATH + priceByDistance)); + kieFileSystem.write(ResourceFactory.newClassPathResource(RULES_PATH + shippingDecision)); + + KieBuilder kb = kieServices.newKieBuilder(kieFileSystem); + kb.buildAll(); + KieModule kieModule = kb.getKieModule(); + + KieContainer kContainer = kieServices.newKieContainer(kieModule.getReleaseId()); + + return kContainer.newKieSession(); + + } + + public KieSession getKieSession(Resource dt) { + KieFileSystem kieFileSystem = kieServices.newKieFileSystem() + .write(dt); + + KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem) + .buildAll(); + + KieRepository kieRepository = kieServices.getRepository(); + + ReleaseId krDefaultReleaseId = kieRepository.getDefaultReleaseId(); + + KieContainer kieContainer = kieServices.newKieContainer(krDefaultReleaseId); + + return kieContainer.newKieSession(); + } + + /* + * Can be used for debugging + * Input excelFile example: com/baeldung/drools/rules/Discount.xls + */ + public String getDrlFromExcel(String excelFile) { + DecisionTableConfiguration configuration = KnowledgeBuilderFactory.newDecisionTableConfiguration(); + configuration.setInputType(DecisionTableInputType.XLS); + + Resource dt = ResourceFactory.newClassPathResource(excelFile, getClass()); + + DecisionTableProviderImpl decisionTableProvider = new DecisionTableProviderImpl(); + + return decisionTableProvider.loadFromResource(dt, null); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/ModulesConfiguration.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/ModulesConfiguration.java new file mode 100644 index 0000000000..d134c9cf60 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/ModulesConfiguration.java @@ -0,0 +1,44 @@ +package com.salesmanager.core.business.configuration; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; + +import com.salesmanager.core.modules.integration.payment.model.PaymentModule; +import com.salesmanager.core.modules.integration.shipping.model.ShippingQuoteModule; + +/** + * Contains injection of external shopizer starter modules + * @author carlsamson + * New Way - out of xml config and using spring boot starters + * + */ +@Configuration +public class ModulesConfiguration { + + private static final Logger LOGGER = LoggerFactory.getLogger(ModulesConfiguration.class); + + + /** + * Goes along with + * shipping-canadapost-spring-boot-starter + */ + @Autowired + private ShippingQuoteModule canadapost; + + + /** + * All living modules exposed here + */ + @Autowired + private List liveModules; + + + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/ProcessorsConfiguration.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/ProcessorsConfiguration.java new file mode 100644 index 0000000000..df6f736f72 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/ProcessorsConfiguration.java @@ -0,0 +1,55 @@ +package com.salesmanager.core.business.configuration; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.salesmanager.core.business.modules.order.total.PromoCodeCalculatorModule; +import com.salesmanager.core.modules.order.total.OrderTotalPostProcessorModule; + +/** + * Pre and post processors triggered during certain actions such as + * order processing and shopping cart processing + * + * 2 types of processors + * - functions processors + * Triggered during defined simple events - ex add to cart checkout + * + * - calculation processors + * Triggered during shopping cart and order total calculation + * + * For events see configuratio/events + * + * - Payment events (payment, refund) + * + * - Change Order status + * + * @author carlsamson + * + */ +@Configuration +public class ProcessorsConfiguration { + + @Inject + private PromoCodeCalculatorModule promoCodeCalculatorModule; + + + /** + * Calculate processors + * @return + */ + @Bean + public List orderTotalsPostProcessors() { + + List processors = new ArrayList(); + ///processors.add(new com.salesmanager.core.business.modules.order.total.ManufacturerShippingCodeOrderTotalModuleImpl()); + processors.add(promoCodeCalculatorModule); + return processors; + + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/db/DbConfig.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/db/DbConfig.java new file mode 100755 index 0000000000..c848e47dc4 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/db/DbConfig.java @@ -0,0 +1,20 @@ +package com.salesmanager.core.business.configuration.db; + +import javax.inject.Inject; +import org.springframework.context.annotation.Bean; +import org.springframework.core.env.Environment; +import com.salesmanager.core.model.system.credentials.DbCredentials; + +public class DbConfig { + + @Inject Environment env; + + @Bean + public DbCredentials dbCredentials() { + DbCredentials dbCredentials = new DbCredentials(); + dbCredentials.setUserName(env.getProperty("user")); + dbCredentials.setPassword(env.getProperty("password")); + return dbCredentials; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/AsynchronousEventsConfiguration.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/AsynchronousEventsConfiguration.java new file mode 100644 index 0000000000..6091503d58 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/AsynchronousEventsConfiguration.java @@ -0,0 +1,26 @@ +package com.salesmanager.core.business.configuration.events; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.event.ApplicationEventMulticaster; +import org.springframework.context.event.SimpleApplicationEventMulticaster; +import org.springframework.core.task.SimpleAsyncTaskExecutor; + +/** + * Events will be asynchronous (in a different thread) + * @author carlsamson + * + */ +@Configuration +public class AsynchronousEventsConfiguration { + + @Bean(name = "applicationEventMulticaster") + public ApplicationEventMulticaster simpleApplicationEventMulticaster() { + SimpleApplicationEventMulticaster eventMulticaster + = new SimpleApplicationEventMulticaster(); + + eventMulticaster.setTaskExecutor(new SimpleAsyncTaskExecutor()); + return eventMulticaster; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/DeleteProductAttributeEvent.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/DeleteProductAttributeEvent.java new file mode 100644 index 0000000000..7128b555c5 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/DeleteProductAttributeEvent.java @@ -0,0 +1,21 @@ +package com.salesmanager.core.business.configuration.events.products; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; + +public class DeleteProductAttributeEvent extends ProductEvent { + + + private static final long serialVersionUID = 1L; + private ProductAttribute productAttribute; + + public DeleteProductAttributeEvent(Object source, ProductAttribute productAttribute, Product product) { + super(source, product); + this.productAttribute=productAttribute; + } + + public ProductAttribute getProductAttribute() { + return productAttribute; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/DeleteProductEvent.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/DeleteProductEvent.java new file mode 100644 index 0000000000..11934bce98 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/DeleteProductEvent.java @@ -0,0 +1,13 @@ +package com.salesmanager.core.business.configuration.events.products; + +import com.salesmanager.core.model.catalog.product.Product; + +public class DeleteProductEvent extends ProductEvent { + + private static final long serialVersionUID = 1L; + + public DeleteProductEvent(Object source, Product product) { + super(source, product); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/DeleteProductImageEvent.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/DeleteProductImageEvent.java new file mode 100644 index 0000000000..565ab3e015 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/DeleteProductImageEvent.java @@ -0,0 +1,23 @@ +package com.salesmanager.core.business.configuration.events.products; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.image.ProductImage; + +public class DeleteProductImageEvent extends ProductEvent { + + + private static final long serialVersionUID = 1L; + private ProductImage productImage; + + public ProductImage getProductImage() { + return productImage; + } + + public DeleteProductImageEvent(Object source, ProductImage productImage, Product product) { + super(source, product); + this.productImage = productImage; + + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/DeleteProductVariantEvent.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/DeleteProductVariantEvent.java new file mode 100644 index 0000000000..3520e492fe --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/DeleteProductVariantEvent.java @@ -0,0 +1,20 @@ +package com.salesmanager.core.business.configuration.events.products; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; + +public class DeleteProductVariantEvent extends ProductEvent { + + private static final long serialVersionUID = 1L; + private ProductVariant variant; + + public DeleteProductVariantEvent(Object source, ProductVariant variant, Product product) { + super(source, product); + this.variant = variant; + } + + public ProductVariant getVariant() { + return variant; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/ProductAttributeEvent.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/ProductAttributeEvent.java new file mode 100644 index 0000000000..c76a8fb6c3 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/ProductAttributeEvent.java @@ -0,0 +1,13 @@ +package com.salesmanager.core.business.configuration.events.products; + +import com.salesmanager.core.model.catalog.product.Product; + +public class ProductAttributeEvent extends ProductEvent { + + private static final long serialVersionUID = 1L; + + public ProductAttributeEvent(Object source, Product product) { + super(source, product); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/ProductEvent.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/ProductEvent.java new file mode 100644 index 0000000000..0034a7dbd3 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/ProductEvent.java @@ -0,0 +1,22 @@ +package com.salesmanager.core.business.configuration.events.products; + +import org.springframework.context.ApplicationEvent; + +import com.salesmanager.core.model.catalog.product.Product; + +public abstract class ProductEvent extends ApplicationEvent { + + private static final long serialVersionUID = 1L; + private Product product; + + public ProductEvent(Object source, Product product) { + super(source); + this.product = product; + } + + + public Product getProduct() { + return product; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/PublishProductAspect.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/PublishProductAspect.java new file mode 100644 index 0000000000..0cd6979be6 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/PublishProductAspect.java @@ -0,0 +1,144 @@ +package com.salesmanager.core.business.configuration.events.products; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; + +/** + * Aspect class that will trigger an event once a product is created Code + * inspired from http://www.discoversdk.com/blog/spring-event-handling-and-aop + * + * create product + * update product + * delete product + * + * decorate + * product variant + * product attribute + * product image + * + * @author carlsamson + * + */ + +@Component +@Aspect +public class PublishProductAspect { + + private ApplicationEventPublisher eventPublisher; + + @Autowired + public void setEventPublisher(ApplicationEventPublisher eventPublisher) { + this.eventPublisher = eventPublisher; + } + + @Pointcut("@target(org.springframework.stereotype.Service)") + public void serviceMethods() { + } + + /** + * Product + */ + + // save product + + @Pointcut("execution(* com.salesmanager.core.business.services.catalog.product.ProductService.saveProduct(com.salesmanager.core.model.catalog.product.Product))") + public void saveProductMethod() { + } + + @Pointcut("serviceMethods() && saveProductMethod()") + public void entityCreationMethods() { + } + + @AfterReturning(value = "entityCreationMethods()", returning = "entity") + public void createProductEvent(JoinPoint jp, Object entity) throws Throwable { + eventPublisher.publishEvent(new SaveProductEvent(eventPublisher, (Product)entity)); + } + + // delete product + + @After("execution(* com.salesmanager.core.business.services.catalog.product.ProductService.delete(com.salesmanager.core.model.catalog.product.Product))") + public void logBeforeDeleteProduct(JoinPoint joinPoint) { + Object[] signatureArgs = joinPoint.getArgs(); + eventPublisher.publishEvent(new DeleteProductEvent(eventPublisher, (Product)signatureArgs[0])); + } + + // save variant + + @Pointcut("execution(* com.salesmanager.core.business.services.catalog.product.variant.ProductVariantService.saveProductVariant(com.salesmanager.core.model.catalog.product.variant.ProductVariant))") + public void saveProductVariantMethod() { + } + + @Pointcut("serviceMethods() && saveProductVariantMethod()") + public void entityProductVariantCreationMethods() { + } + + @AfterReturning(value = "entityProductVariantCreationMethods()", returning = "entity") + public void createProductVariantEvent(JoinPoint jp, Object entity) throws Throwable { + eventPublisher.publishEvent(new SaveProductVariantEvent(eventPublisher, (ProductVariant)entity, ((ProductVariant)entity).getProduct())); + } + + // delete product variant + + @After("execution(* com.salesmanager.core.business.services.catalog.product.variant.ProductVariantService.delete(com.salesmanager.core.model.catalog.product.variant.ProductVariant))") + public void logBeforeDeleteProductVariant(JoinPoint joinPoint) { + Object[] signatureArgs = joinPoint.getArgs(); + eventPublisher.publishEvent(new DeleteProductVariantEvent(eventPublisher, (ProductVariant)signatureArgs[0], ((ProductVariant)signatureArgs[0]).getProduct())); + } + + //product image + + @Pointcut("execution(* com.salesmanager.core.business.services.catalog.product.image.ProductImageService.saveOrUpdate(com.salesmanager.core.model.catalog.product.image.ProductImage))") + public void saveProductImageMethod() { + } + + @Pointcut("serviceMethods() && saveProductImageMethod()") + public void entityProductImageCreationMethods() { + } + + @AfterReturning(value = "entityProductImageCreationMethods()", returning = "entity") + public void createProductImageEvent(JoinPoint jp, Object entity) throws Throwable { + eventPublisher.publishEvent(new SaveProductImageEvent(eventPublisher, (ProductImage)entity, ((ProductImage)entity).getProduct())); + } + + @After("execution(* com.salesmanager.core.business.services.catalog.product.image.ProductImageService.delete(com.salesmanager.core.model.catalog.product.image.ProductImage))") + public void logBeforeDeleteProductImage(JoinPoint joinPoint) { + Object[] signatureArgs = joinPoint.getArgs(); + eventPublisher.publishEvent(new DeleteProductImageEvent(eventPublisher, (ProductImage)signatureArgs[0], ((ProductImage)signatureArgs[0]).getProduct())); + } + + + //attributes + + @Pointcut("execution(* com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService.saveOrUpdate(com.salesmanager.core.model.catalog.product.attribute.ProductAttribute))") + public void saveProductAttributeMethod() { + } + + @Pointcut("serviceMethods() && saveProductAttributeMethod()") + public void entityProductAttributeCreationMethods() { + } + + @AfterReturning(value = "entityProductAttributeCreationMethods()", returning = "entity") + public void createProductAttributeEvent(JoinPoint jp, Object entity) throws Throwable { + eventPublisher.publishEvent(new SaveProductAttributeEvent(eventPublisher, (ProductAttribute)entity, ((ProductAttribute)entity).getProduct())); + } + + @After("execution(* com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService.delete(com.salesmanager.core.model.catalog.product.attribute.ProductAttribute))") + public void logBeforeDeleteProductAttribute(JoinPoint joinPoint) { + Object[] signatureArgs = joinPoint.getArgs(); + eventPublisher.publishEvent(new DeleteProductAttributeEvent(eventPublisher, (ProductAttribute)signatureArgs[0], ((ProductAttribute)signatureArgs[0]).getProduct())); + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/SaveProductAttributeEvent.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/SaveProductAttributeEvent.java new file mode 100644 index 0000000000..a767145b15 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/SaveProductAttributeEvent.java @@ -0,0 +1,21 @@ +package com.salesmanager.core.business.configuration.events.products; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; + +public class SaveProductAttributeEvent extends ProductEvent { + + + private static final long serialVersionUID = 1L; + private ProductAttribute productAttribute; + + public SaveProductAttributeEvent(Object source, ProductAttribute productAttribute, Product product) { + super(source, product); + this.productAttribute=productAttribute; + } + + public ProductAttribute getProductAttribute() { + return productAttribute; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/SaveProductEvent.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/SaveProductEvent.java new file mode 100644 index 0000000000..0e6f3b50cd --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/SaveProductEvent.java @@ -0,0 +1,16 @@ +package com.salesmanager.core.business.configuration.events.products; + +import com.salesmanager.core.model.catalog.product.Product; + +public class SaveProductEvent extends ProductEvent { + + public SaveProductEvent(Object source, Product product) { + super(source, product); + } + + private static final long serialVersionUID = 1L; + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/SaveProductImageEvent.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/SaveProductImageEvent.java new file mode 100644 index 0000000000..69cfb66fbf --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/SaveProductImageEvent.java @@ -0,0 +1,23 @@ +package com.salesmanager.core.business.configuration.events.products; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.image.ProductImage; + +public class SaveProductImageEvent extends ProductEvent { + + + private static final long serialVersionUID = 1L; + private ProductImage productImage; + + public ProductImage getProductImage() { + return productImage; + } + + public SaveProductImageEvent(Object source, ProductImage productImage, Product product) { + super(source, product); + this.productImage = productImage; + + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/SaveProductVariantEvent.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/SaveProductVariantEvent.java new file mode 100644 index 0000000000..7a412a3e1e --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/SaveProductVariantEvent.java @@ -0,0 +1,21 @@ +package com.salesmanager.core.business.configuration.events.products; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; + +public class SaveProductVariantEvent extends ProductEvent { + + private static final long serialVersionUID = 1L; + private ProductVariant variant; + + public SaveProductVariantEvent(Object source, ProductVariant variant, Product product) { + super(source, product); + this.variant = variant; + } + + public ProductVariant getVariant() { + return variant; + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/listeners/IndexProductEventListener.java b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/listeners/IndexProductEventListener.java new file mode 100644 index 0000000000..2d5cb79444 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/configuration/events/products/listeners/IndexProductEventListener.java @@ -0,0 +1,319 @@ +package com.salesmanager.core.business.configuration.events.products.listeners; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.configuration.events.products.DeleteProductAttributeEvent; +import com.salesmanager.core.business.configuration.events.products.DeleteProductEvent; +import com.salesmanager.core.business.configuration.events.products.DeleteProductImageEvent; +import com.salesmanager.core.business.configuration.events.products.DeleteProductVariantEvent; +import com.salesmanager.core.business.configuration.events.products.ProductEvent; +import com.salesmanager.core.business.configuration.events.products.SaveProductAttributeEvent; +import com.salesmanager.core.business.configuration.events.products.SaveProductEvent; +import com.salesmanager.core.business.configuration.events.products.SaveProductImageEvent; +import com.salesmanager.core.business.configuration.events.products.SaveProductVariantEvent; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.search.SearchService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.merchant.MerchantStore; + +/** + * Index product in search module if it is configured to do so ! + * + * Should receive events that a product was created or updated or deleted + * + * @author carlsamson + * + */ +@Component +public class IndexProductEventListener implements ApplicationListener { + + @Autowired + private SearchService searchService; + + @Autowired + private ProductService productService; + + @Value("${search.noindex:false}")//skip indexing process + private boolean noIndex; + + /** + * Listens to ProductEvent and ProductVariantEvent + */ + @Override + public void onApplicationEvent(ProductEvent event) { + + + if(!noIndex) { + + if (event instanceof SaveProductEvent) { + saveProduct((SaveProductEvent) event); + } + + if (event instanceof DeleteProductEvent) { + deleteProduct((DeleteProductEvent) event); + } + + if (event instanceof SaveProductVariantEvent) { + saveProductVariant((SaveProductVariantEvent) event); + } + + if (event instanceof DeleteProductVariantEvent) { + deleteProductVariant((DeleteProductVariantEvent) event); + } + + if (event instanceof SaveProductImageEvent) { + saveProductImage((SaveProductImageEvent) event); + } + + if (event instanceof DeleteProductImageEvent) { + deleteProductImage((DeleteProductImageEvent) event); + } + + if (event instanceof SaveProductAttributeEvent) { + saveProductAttribute((SaveProductAttributeEvent) event); + } + + if (event instanceof DeleteProductAttributeEvent) { + deleteProductAttribute((DeleteProductAttributeEvent) event); + } + + + + } + + } + + private Product productOfEvent(ProductEvent event) { + + Product product = event.getProduct(); + MerchantStore store = product.getMerchantStore(); + try { + + /** + * Refresh product + */ + + Product fullProduct = productService.findOne(product.getId(), store); + + if(fullProduct != null) { + product = fullProduct; + } else { + System.out.println("Product not loaded"); + } + + return product; + + } catch (Exception e) { + throw new RuntimeException(e); + } + + } + + void saveProduct(SaveProductEvent event) { + + try { + Product product = productOfEvent(event); + MerchantStore store = product.getMerchantStore(); + + searchService.index(store, product); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + void deleteProduct(DeleteProductEvent event) { + + Product product = event.getProduct(); + MerchantStore store = product.getMerchantStore(); + + try { + searchService.deleteDocument(store, product); + } catch (ServiceException e) { + throw new RuntimeException(e); + } + } + + void saveProductVariant(SaveProductVariantEvent event) { + + Product product = productOfEvent(event); + + MerchantStore store = product.getMerchantStore(); + + ProductVariant variant = event.getVariant();// to be removed + + /** + * add new variant to be saved + **/ + + List filteredVariants = product.getVariants().stream() + .filter(i -> variant.getId().longValue() != i.getId().longValue()).collect(Collectors.toList()); + + filteredVariants.add(variant); + + Set allVariants = new HashSet(filteredVariants); + product.setVariants(allVariants); + + try { + searchService.index(store, product); + } catch (ServiceException e) { + throw new RuntimeException(e); + } + + } + + void deleteProductVariant(DeleteProductVariantEvent event) { + + Product product = productOfEvent(event); + + MerchantStore store = product.getMerchantStore(); + + ProductVariant variant = event.getVariant();// to be removed + + /** + * remove variant to be saved + **/ + + List filteredVariants = product.getVariants().stream() + .filter(i -> variant.getId().longValue() != i.getId().longValue()).collect(Collectors.toList()); + + Set allVariants = new HashSet(filteredVariants); + product.setVariants(allVariants); + + try { + searchService.index(store, product); + } catch (ServiceException e) { + throw new RuntimeException(e); + } + + } + + + void saveProductImage(SaveProductImageEvent event) { + + Product product = productOfEvent(event); + + MerchantStore store = product.getMerchantStore(); + + + ProductImage image = event.getProductImage();// to be removed + + /** + * add new image to be saved + **/ + + List filteredImages = product.getImages().stream() + .filter(i -> i.getId().longValue() != i.getId().longValue()).collect(Collectors.toList()); + + filteredImages.add(image); + + Set allInmages = new HashSet(filteredImages); + product.setImages(allInmages); + + try { + searchService.index(store, product); + } catch (ServiceException e) { + throw new RuntimeException(e); + } + + } + + void deleteProductImage(DeleteProductImageEvent event) { + + //Product will be updated anyway so there is no need to reindex following an image removal + return; + + /** + + Product product = productOfEvent(event); + + MerchantStore store = product.getMerchantStore(); + + List filteredImages = product.getImages().stream() + .filter(i -> i.getId().longValue() != i.getId().longValue()).collect(Collectors.toList()); + + + Set allImages = new HashSet(filteredImages); + product.setImages(allImages); + + try { + + + //searchService.index(store, product); + } catch (ServiceException e) { + throw new RuntimeException(e); + } + **/ + + } + + void saveProductAttribute(SaveProductAttributeEvent event) { + + Product product = productOfEvent(event); + + MerchantStore store = product.getMerchantStore(); + + ProductAttribute attribute = event.getProductAttribute();// to be removed + + /** + * add new attribute to be saved + **/ + + List filteredAttributes = product.getAttributes().stream() + .filter(i -> i.getId().longValue() != i.getId().longValue()).collect(Collectors.toList()); + + filteredAttributes.add(attribute); + + Set allAttributes = new HashSet(filteredAttributes); + product.setAttributes(allAttributes); + + try { + searchService.index(store, product); + } catch (ServiceException e) { + throw new RuntimeException(e); + } + + } + + void deleteProductAttribute(DeleteProductAttributeEvent event) { + + Product product = productOfEvent(event); + + MerchantStore store = product.getMerchantStore(); + + /** + * add new attribute to be saved + **/ + + List filteredAttributes = product.getAttributes().stream() + .filter(i -> i.getId().longValue() != i.getId().longValue()).collect(Collectors.toList()); + + Set allAttributes = new HashSet(filteredAttributes); + product.setAttributes(allAttributes); + + try { + searchService.index(store, product); + } catch (ServiceException e) { + throw new RuntimeException(e); + } + + } + + /** + * Get document by product id and document exist if event is Product delete + * document create document if event is Variant get document get variants + * replace variant + */ + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/constants/Constants.java b/sm-core/src/main/java/com/salesmanager/core/business/constants/Constants.java new file mode 100755 index 0000000000..b60e4b3af6 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/constants/Constants.java @@ -0,0 +1,53 @@ +package com.salesmanager.core.business.constants; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Currency; +import java.util.Locale; + +/** + * Constants used for sm-core + * + * @author carlsamson + * + */ +public class Constants { + + public static final Charset ISO_8859_1 = StandardCharsets.ISO_8859_1; + public static final Charset UTF_8 = StandardCharsets.UTF_8; + + public final static String TEST_ENVIRONMENT = "TEST"; + public final static String PRODUCTION_ENVIRONMENT = "PROD"; + public final static String SHOP_URI = "/shop"; + + public static final String ALL_REGIONS = "*"; + + + public final static String DEFAULT_DATE_FORMAT = "yyyy-MM-dd"; + public final static String DEFAULT_DATE_FORMAT_YEAR = "yyyy"; + public final static String DEFAULT_LANGUAGE = "en"; + public final static String DEFAULT_COUNTRY = "CA"; + + public final static String EMAIL_CONFIG = "EMAIL_CONFIG"; + + public final static String UNDERSCORE = "_"; + public final static String SLASH = "/"; + public final static String TRUE = "true"; + public final static String FALSE = "false"; + public final static String OT_ITEM_PRICE_MODULE_CODE = "itemprice"; + public final static String OT_SUBTOTAL_MODULE_CODE = "subtotal"; + public final static String OT_TOTAL_MODULE_CODE = "total"; + public final static String OT_SHIPPING_MODULE_CODE = "shipping"; + public final static String OT_HANDLING_MODULE_CODE = "handling"; + public final static String OT_TAX_MODULE_CODE = "tax"; + public final static String OT_REFUND_MODULE_CODE = "refund"; + public final static String OT_DISCOUNT_TITLE = "order.total.discount"; + + public final static String DEFAULT_STORE = "DEFAULT"; + + public final static Locale DEFAULT_LOCALE = Locale.US; + public final static Currency DEFAULT_CURRENCY = Currency.getInstance(Locale.US); + + public final static String PAYMENT_MODULES = "PAYMENT"; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/constants/ShippingConstants.java b/sm-core/src/main/java/com/salesmanager/core/business/constants/ShippingConstants.java new file mode 100755 index 0000000000..a067b4d6ce --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/constants/ShippingConstants.java @@ -0,0 +1,10 @@ +package com.salesmanager.core.business.constants; + + +public class ShippingConstants { + + public final static String SHIPPING_CONFIGURATION = "SHIPPING_CONFIG"; + public final static String SHIPPING_NATIONAL = "NATIONAL"; + public final static String SHIPPING_INTERNATIONAL = "INTERNATIONAL"; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/constants/SystemConstants.java b/sm-core/src/main/java/com/salesmanager/core/business/constants/SystemConstants.java new file mode 100755 index 0000000000..218207003d --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/constants/SystemConstants.java @@ -0,0 +1,12 @@ +package com.salesmanager.core.business.constants; + +public class SystemConstants { + + + + public final static String SYSTEM_USER = "SYSTEM"; + public final static String CONFIG_VALUE_TRUE = "true"; + public final static String CONFIG_VALUE_FALSE = "false"; + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/common/AssetsManager.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/common/AssetsManager.java new file mode 100755 index 0000000000..d88249b2e5 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/common/AssetsManager.java @@ -0,0 +1,5 @@ +package com.salesmanager.core.business.modules.cms.common; + +public interface AssetsManager { + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/common/ImageGet.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/common/ImageGet.java new file mode 100755 index 0000000000..a9b4715e00 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/common/ImageGet.java @@ -0,0 +1,14 @@ +package com.salesmanager.core.business.modules.cms.common; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.OutputContentFile; + +import java.util.List; + +public interface ImageGet { + + List getImages(final String merchantStoreCode, + FileContentType imageContentType) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/common/ImageRemove.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/common/ImageRemove.java new file mode 100755 index 0000000000..c6f823f08f --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/common/ImageRemove.java @@ -0,0 +1,10 @@ +package com.salesmanager.core.business.modules.cms.common; + +import com.salesmanager.core.business.exception.ServiceException; + + +public interface ImageRemove { + + void removeImages(final String merchantStoreCode) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/ContentAssetsManager.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/ContentAssetsManager.java new file mode 100755 index 0000000000..e47c4070c0 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/ContentAssetsManager.java @@ -0,0 +1,83 @@ +package com.salesmanager.core.business.modules.cms.content; + +import java.io.ByteArrayOutputStream; +import java.io.Serializable; +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.modules.cms.common.AssetsManager; +import com.salesmanager.core.business.modules.cms.impl.CMSManager; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.OutputContentFile; + +import org.apache.commons.lang3.StringUtils; + +public interface ContentAssetsManager extends AssetsManager, FileGet, FilePut, FileRemove, FolderPut, FolderList, FolderRemove, Serializable { + public static final char UNIX_SEPARATOR = '/'; + public static final char WINDOWS_SEPARATOR = '\\'; + public static String DEFAULT_BUCKET_NAME = "shopizer"; + public static String DEFAULT_REGION_NAME = "us-east-1"; + public static final String ROOT_NAME = "files"; + + CMSManager getCmsManager(); + + default String bucketName() { + String name = getCmsManager().getRootName(); + if (StringUtils.isBlank(name)) { + name = DEFAULT_BUCKET_NAME; + } + return name; + } + + default String nodePath(String store, FileContentType type) { + + StringBuilder builder = new StringBuilder(); + String root = nodePath(store); + builder.append(root); + if (type != null && !FileContentType.IMAGE.name().equals(type.name()) && !FileContentType.STATIC_FILE.name().equals(type.name())) { + builder.append(type.name()).append(Constants.SLASH); + } + + return builder.toString(); + + } + + default String nodePath(String store) { + + StringBuilder builder = new StringBuilder(); + builder.append(ROOT_NAME).append(Constants.SLASH).append(store).append(Constants.SLASH); + return builder.toString(); + + } + + default OutputContentFile getOutputContentFile(byte[] byteArray) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(byteArray.length); + baos.write(byteArray, 0, byteArray.length); + OutputContentFile ct = new OutputContentFile(); + ct.setFile(baos); + return ct; + } + + default boolean isInsideSubFolder(String key) { + int c = StringUtils.countMatches(key, Constants.SLASH); + return c > 2; + } + + default String getName(String filename) { + if (filename == null) { + return null; + } + int index = indexOfLastSeparator(filename); + return filename.substring(index + 1); + } + + default int indexOfLastSeparator(String filename) { + if (filename == null) { + return -1; + } + int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR); + int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR); + return Math.max(lastUnixPos, lastWindowsPos); + } + + + +} \ No newline at end of file diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/ContentImageGet.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/ContentImageGet.java new file mode 100755 index 0000000000..11f33d05c2 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/ContentImageGet.java @@ -0,0 +1,17 @@ +package com.salesmanager.core.business.modules.cms.content; + +import java.util.List; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.cms.common.ImageGet; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.OutputContentFile; + +public interface ContentImageGet extends ImageGet { + + OutputContentFile getImage(final String merchantStoreCode, String imageName, + FileContentType imageContentType) throws ServiceException; + + List getImageNames(final String merchantStoreCode, + FileContentType imageContentType) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/ContentImageRemove.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/ContentImageRemove.java new file mode 100755 index 0000000000..30cec4fc33 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/ContentImageRemove.java @@ -0,0 +1,15 @@ +package com.salesmanager.core.business.modules.cms.content; + + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.cms.common.ImageRemove; +import com.salesmanager.core.model.content.FileContentType; + +public interface ContentImageRemove extends ImageRemove { + + + + void removeImage(final String merchantStoreCode, final FileContentType imageContentType, + final String imageName) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FileGet.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FileGet.java new file mode 100755 index 0000000000..03e0535dcb --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FileGet.java @@ -0,0 +1,27 @@ +package com.salesmanager.core.business.modules.cms.content; + +import java.util.List; +import java.util.Optional; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.OutputContentFile; + + +/** + * Methods to retrieve the static content from the CMS + * + * @author Carl Samson + * + */ +public interface FileGet { + + OutputContentFile getFile(final String merchantStoreCode, Optional path, FileContentType fileContentType, + String contentName) throws ServiceException; + + List getFileNames(final String merchantStoreCode, Optional path, FileContentType fileContentType) + throws ServiceException; + + List getFiles(final String merchantStoreCode, + Optional path, FileContentType fileContentType) throws ServiceException; +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FilePut.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FilePut.java new file mode 100755 index 0000000000..07fa8f7dd7 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FilePut.java @@ -0,0 +1,39 @@ +/** + * + */ +package com.salesmanager.core.business.modules.cms.content; + +import java.util.List; +import java.util.Optional; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.content.InputContentFile; + + +/** + * @author Umesh Awasthi + * + */ + +public interface FilePut { + + /** + * Add file to folder + * @param merchantStoreCode + * @param path + * @param inputStaticContentData + * @throws ServiceException + */ + void addFile(final String merchantStoreCode, Optional path, InputContentFile inputStaticContentData) + throws ServiceException; + + /** + * Add files to folder + * @param merchantStoreCode + * @param path + * @param inputStaticContentDataList + * @throws ServiceException + */ + void addFiles(final String merchantStoreCode, + Optional path, List inputStaticContentDataList) throws ServiceException; +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FileRemove.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FileRemove.java new file mode 100755 index 0000000000..e03e7de772 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FileRemove.java @@ -0,0 +1,22 @@ +/** + * + */ +package com.salesmanager.core.business.modules.cms.content; + +import java.util.Optional; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.content.FileContentType; + + +/** + * @author Umesh Awasthi + * + */ +public interface FileRemove { + void removeFile(String merchantStoreCode, FileContentType staticContentType, + String fileName, Optional path) throws ServiceException; + + void removeFiles(String merchantStoreCode, Optional path) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FolderList.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FolderList.java new file mode 100644 index 0000000000..b1dfc68caa --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FolderList.java @@ -0,0 +1,13 @@ +package com.salesmanager.core.business.modules.cms.content; + +import java.util.List; +import java.util.Optional; + +import com.salesmanager.core.business.exception.ServiceException; + +public interface FolderList { + + List listFolders(final String merchantStoreCode, Optional path) + throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FolderPut.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FolderPut.java new file mode 100644 index 0000000000..4cdee3f533 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FolderPut.java @@ -0,0 +1,24 @@ +/** + * + */ +package com.salesmanager.core.business.modules.cms.content; + +import java.util.Optional; + +import com.salesmanager.core.business.exception.ServiceException; + + +public interface FolderPut { + + + /** + * Create folder on root or on specific path + * @param merchantStoreCode + * @param folderName + * @param path + * @throws ServiceException + */ + void addFolder(final String merchantStoreCode, String folderName, Optional path) + throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FolderRemove.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FolderRemove.java new file mode 100644 index 0000000000..3ac5e9fda5 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/FolderRemove.java @@ -0,0 +1,15 @@ +/** + * + */ +package com.salesmanager.core.business.modules.cms.content; + +import java.util.Optional; + +import com.salesmanager.core.business.exception.ServiceException; + + +public interface FolderRemove { + void removeFolder(final String merchantStoreCode, String folderName, Optional folderPath) + throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/ImagePut.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/ImagePut.java new file mode 100755 index 0000000000..e28b0f381f --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/ImagePut.java @@ -0,0 +1,16 @@ +package com.salesmanager.core.business.modules.cms.content; + +import java.util.List; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.content.InputContentFile; + +public interface ImagePut { + + + void addImage(final String merchantStoreCode, InputContentFile image) + throws ServiceException; + + void addImages(final String merchantStoreCode, List imagesList) + throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/StaticContentFileManager.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/StaticContentFileManager.java new file mode 100755 index 0000000000..1c180b3357 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/StaticContentFileManager.java @@ -0,0 +1,18 @@ +/** + * + */ +package com.salesmanager.core.business.modules.cms.content; + +/** + * @author Umesh Awasthi + * + */ +public abstract class StaticContentFileManager + implements ContentAssetsManager { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/StaticContentFileManagerImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/StaticContentFileManagerImpl.java new file mode 100755 index 0000000000..66fa7a6f7c --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/StaticContentFileManagerImpl.java @@ -0,0 +1,158 @@ +/** + * + */ +package com.salesmanager.core.business.modules.cms.content; + +import java.util.List; +import java.util.Optional; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.cms.content.infinispan.CmsStaticContentFileManagerImpl; +import com.salesmanager.core.business.modules.cms.impl.CMSManager; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.InputContentFile; +import com.salesmanager.core.model.content.OutputContentFile; + +/** + * @author Umesh Awasthi + * + */ +public class StaticContentFileManagerImpl extends StaticContentFileManager { + + /** + * + */ + private static final long serialVersionUID = 1L; + private FilePut uploadFile; + private FileGet getFile; + private FileRemove removeFile; + private FolderRemove removeFolder; + private FolderPut addFolder; + private FolderList listFolder; + + @Override + public void addFile(final String merchantStoreCode, Optional path, final InputContentFile inputContentFile) + throws ServiceException { + uploadFile.addFile(merchantStoreCode, path, inputContentFile); + + } + + /** + * Implementation for add static data files. This method will called + * respected add files method of underlying CMSStaticContentManager. For CMS + * Content files {@link CmsStaticContentFileManagerImpl} will take care of + * adding given content images with Infinispan cache. + * + * @param merchantStoreCode + * merchant store. + * @param inputStaticContentDataList + * Input content images + * @throws ServiceException + */ + @Override + public void addFiles(final String merchantStoreCode, Optional path, final List inputStaticContentDataList) + throws ServiceException { + uploadFile.addFiles(merchantStoreCode, path, inputStaticContentDataList); + } + + @Override + public void removeFile(final String merchantStoreCode, final FileContentType staticContentType, + final String fileName, Optional path) throws ServiceException { + removeFile.removeFile(merchantStoreCode, staticContentType, fileName, path); + + } + + @Override + public OutputContentFile getFile(String merchantStoreCode, Optional path, FileContentType fileContentType, String contentName) + throws ServiceException { + return getFile.getFile(merchantStoreCode, path, fileContentType, contentName); + } + + @Override + public List getFileNames(String merchantStoreCode, Optional path, FileContentType fileContentType) + throws ServiceException { + return getFile.getFileNames(merchantStoreCode, path, fileContentType); + } + + @Override + public List getFiles(String merchantStoreCode, Optional path, FileContentType fileContentType) + throws ServiceException { + return getFile.getFiles(merchantStoreCode, path, fileContentType); + } + + @Override + public void removeFiles(String merchantStoreCode, Optional path) throws ServiceException { + removeFile.removeFiles(merchantStoreCode, path); + } + + public void setRemoveFile(FileRemove removeFile) { + this.removeFile = removeFile; + } + + public FileRemove getRemoveFile() { + return removeFile; + } + + public void setGetFile(FileGet getFile) { + this.getFile = getFile; + } + + public FileGet getGetFile() { + return getFile; + } + + public void setUploadFile(FilePut uploadFile) { + this.uploadFile = uploadFile; + } + + public FilePut getUploadFile() { + return uploadFile; + } + + @Override + public void removeFolder(String merchantStoreCode, String folderName, Optional path) throws ServiceException { + this.removeFolder.removeFolder(merchantStoreCode, folderName, path); + + } + + @Override + public void addFolder(String merchantStoreCode, String folderName, Optional path) throws ServiceException { + addFolder.addFolder(merchantStoreCode, folderName, path); + } + + public FolderRemove getRemoveFolder() { + return removeFolder; + } + + public void setRemoveFolder(FolderRemove removeFolder) { + this.removeFolder = removeFolder; + } + + public FolderPut getAddFolder() { + return addFolder; + } + + public void setAddFolder(FolderPut addFolder) { + this.addFolder = addFolder; + } + + @Override + public List listFolders(String merchantStoreCode, Optional path) throws ServiceException { + return this.listFolder.listFolders(merchantStoreCode, path); + } + + public FolderList getListFolder() { + return listFolder; + } + + public void setListFolder(FolderList listFolder) { + this.listFolder = listFolder; + } + + @Override + public CMSManager getCmsManager() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/aws/S3StaticContentAssetsManagerImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/aws/S3StaticContentAssetsManagerImpl.java new file mode 100755 index 0000000000..96a1ff2342 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/aws/S3StaticContentAssetsManagerImpl.java @@ -0,0 +1,322 @@ +package com.salesmanager.core.business.modules.cms.content.aws; + +import java.io.ByteArrayOutputStream; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import com.amazonaws.services.s3.model.AmazonS3Exception; +import com.amazonaws.services.s3.model.Bucket; +import com.amazonaws.services.s3.model.CannedAccessControlList; +import com.amazonaws.services.s3.model.ListObjectsV2Request; +import com.amazonaws.services.s3.model.ListObjectsV2Result; +import com.amazonaws.services.s3.model.ObjectMetadata; +import com.amazonaws.services.s3.model.PutObjectRequest; +import com.amazonaws.services.s3.model.S3Object; +import com.amazonaws.services.s3.model.S3ObjectSummary; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.cms.content.ContentAssetsManager; +import com.salesmanager.core.business.modules.cms.impl.CMSManager; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.InputContentFile; +import com.salesmanager.core.model.content.OutputContentFile; + +/** + * Static content management with S3 + * + * @author carlsamson + * + */ +public class S3StaticContentAssetsManagerImpl implements ContentAssetsManager { + + private static final long serialVersionUID = 1L; + + private static final Logger LOGGER = LoggerFactory.getLogger(S3StaticContentAssetsManagerImpl.class); + + private static S3StaticContentAssetsManagerImpl fileManager = null; + + private CMSManager cmsManager; + + public static S3StaticContentAssetsManagerImpl getInstance() { + + if (fileManager == null) { + fileManager = new S3StaticContentAssetsManagerImpl(); + } + + return fileManager; + + } + + @Override + public OutputContentFile getFile(String merchantStoreCode, Optional folderPath, FileContentType fileContentType, String contentName) + throws ServiceException { + try { + // get buckets + String bucketName = bucketName(); + + final AmazonS3 s3 = s3Client(); + + S3Object o = s3.getObject(bucketName, nodePath(merchantStoreCode, fileContentType) + contentName); + + LOGGER.info("Content getFile"); + return getOutputContentFile(IOUtils.toByteArray(o.getObjectContent())); + } catch (final Exception e) { + LOGGER.error("Error while getting file", e); + throw new ServiceException(e); + + } + } + + @Override + public List getFileNames(String merchantStoreCode, Optional folderPath, FileContentType fileContentType) + throws ServiceException { + try { + // get buckets + String bucketName = bucketName(); + + ListObjectsV2Request listObjectsRequest = new ListObjectsV2Request().withBucketName(bucketName) + .withPrefix(nodePath(merchantStoreCode, fileContentType)); + + List fileNames = null; + + final AmazonS3 s3 = s3Client(); + ListObjectsV2Result results = s3.listObjectsV2(listObjectsRequest); + List objects = results.getObjectSummaries(); + for (S3ObjectSummary os : objects) { + if (isInsideSubFolder(os.getKey())) { + continue; + } + if (fileNames == null) { + fileNames = new ArrayList(); + } + String mimetype = URLConnection.guessContentTypeFromName(os.getKey()); + if (!StringUtils.isBlank(mimetype)) { + fileNames.add(getName(os.getKey())); + } + } + + LOGGER.info("Content get file names"); + return fileNames; + } catch (final Exception e) { + LOGGER.error("Error while getting file names", e); + throw new ServiceException(e); + + } + } + + @Override + public List getFiles(String merchantStoreCode, Optional folderPath, FileContentType fileContentType) + throws ServiceException { + try { + // get buckets + String bucketName = bucketName(); + + ListObjectsV2Request listObjectsRequest = new ListObjectsV2Request().withBucketName(bucketName) + .withPrefix(nodePath(merchantStoreCode, fileContentType)); + + List files = null; + final AmazonS3 s3 = s3Client(); + ListObjectsV2Result results = s3.listObjectsV2(listObjectsRequest); + List objects = results.getObjectSummaries(); + for (S3ObjectSummary os : objects) { + if (files == null) { + files = new ArrayList(); + } + String mimetype = URLConnection.guessContentTypeFromName(os.getKey()); + if (!StringUtils.isBlank(mimetype)) { + S3Object o = s3.getObject(bucketName, os.getKey()); + byte[] byteArray = IOUtils.toByteArray(o.getObjectContent()); + ByteArrayOutputStream baos = new ByteArrayOutputStream(byteArray.length); + baos.write(byteArray, 0, byteArray.length); + OutputContentFile ct = new OutputContentFile(); + ct.setFile(baos); + files.add(ct); + } + } + + LOGGER.info("Content getFiles"); + return files; + } catch (final Exception e) { + LOGGER.error("Error while getting files", e); + throw new ServiceException(e); + + } + } + + @Override + public void addFile(String merchantStoreCode, Optional folderPath, InputContentFile inputStaticContentData) throws ServiceException { + + try { + // get buckets + String bucketName = bucketName(); + + String nodePath = nodePath(merchantStoreCode, inputStaticContentData.getFileContentType()); + + final AmazonS3 s3 = s3Client(); + + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentType(inputStaticContentData.getMimeType()); + PutObjectRequest request = new PutObjectRequest(bucketName, nodePath + inputStaticContentData.getFileName(), + inputStaticContentData.getFile(), metadata); + request.setCannedAcl(CannedAccessControlList.PublicRead); + + s3.putObject(request); + + LOGGER.info("Content add file"); + } catch (final Exception e) { + LOGGER.error("Error while adding file", e); + throw new ServiceException(e); + + } + + } + + @Override + public void addFiles(String merchantStoreCode, Optional folderPath, List inputStaticContentDataList) + throws ServiceException { + + if (CollectionUtils.isNotEmpty(inputStaticContentDataList)) { + for (InputContentFile inputFile : inputStaticContentDataList) { + this.addFile(merchantStoreCode, folderPath, inputFile); + } + + } + + } + + @Override + public void removeFile(String merchantStoreCode, FileContentType staticContentType, String fileName, Optional folderPath) + throws ServiceException { + + try { + // get buckets + String bucketName = bucketName(); + + final AmazonS3 s3 = s3Client(); + s3.deleteObject(bucketName, nodePath(merchantStoreCode, staticContentType) + fileName); + + LOGGER.info("Remove file"); + } catch (final Exception e) { + LOGGER.error("Error while removing file", e); + throw new ServiceException(e); + + } + + } + + @Override + public void removeFiles(String merchantStoreCode, Optional folderPath) throws ServiceException { + + try { + // get buckets + String bucketName = bucketName(); + + final AmazonS3 s3 = s3Client(); + s3.deleteObject(bucketName, nodePath(merchantStoreCode)); + + LOGGER.info("Remove folder"); + } catch (final Exception e) { + LOGGER.error("Error while removing folder", e); + throw new ServiceException(e); + + } + + } + + private Bucket getBucket(String bucket_name) { + final AmazonS3 s3 = s3Client(); + Bucket named_bucket = null; + List buckets = s3.listBuckets(); + for (Bucket b : buckets) { + if (b.getName().equals(bucket_name)) { + named_bucket = b; + } + } + + if (named_bucket == null) { + named_bucket = createBucket(bucket_name); + } + + return named_bucket; + } + + private Bucket createBucket(String bucket_name) { + final AmazonS3 s3 = s3Client(); + Bucket b = null; + if (s3.doesBucketExistV2(bucket_name)) { + System.out.format("Bucket %s already exists.\n", bucket_name); + b = getBucket(bucket_name); + } else { + try { + b = s3.createBucket(bucket_name); + } catch (AmazonS3Exception e) { + System.err.println(e.getErrorMessage()); + } + } + return b; + } + + /** + * Builds an amazon S3 client + * + * @return + */ + private AmazonS3 s3Client() { + String region = regionName(); + LOGGER.debug("AWS CMS Using region " + region); + + return AmazonS3ClientBuilder.standard().withRegion(region) // The + // first + // region + // to + // try + // your + // request + // against + .build(); + } + + private String regionName() { + String regionName = getCmsManager().getLocation(); + if (StringUtils.isBlank(regionName)) { + regionName = DEFAULT_REGION_NAME; + } + return regionName; + } + + public CMSManager getCmsManager() { + return cmsManager; + } + + public void setCmsManager(CMSManager cmsManager) { + this.cmsManager = cmsManager; + } + + @Override + public void addFolder(String merchantStoreCode, String folderName, Optional folderPath) throws ServiceException { + // TODO Auto-generated method stub + + } + + @Override + public void removeFolder(String merchantStoreCode, String folderName, Optional folderPath) throws ServiceException { + // TODO Auto-generated method stub + + } + + + @Override + public List listFolders(String merchantStoreCode, Optional path) throws ServiceException { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/gcp/GCPDownloadsManagerImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/gcp/GCPDownloadsManagerImpl.java new file mode 100644 index 0000000000..23ae120664 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/gcp/GCPDownloadsManagerImpl.java @@ -0,0 +1,9 @@ +package com.salesmanager.core.business.modules.cms.content.gcp; + +import org.springframework.stereotype.Component; + +@Component("gcpDownloadsManager") +public class GCPDownloadsManagerImpl extends GCPStaticContentAssetsManagerImpl { + private static final long serialVersionUID = 1L; + +} \ No newline at end of file diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/gcp/GCPStaticContentAssetsManagerImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/gcp/GCPStaticContentAssetsManagerImpl.java new file mode 100755 index 0000000000..301f3a6371 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/gcp/GCPStaticContentAssetsManagerImpl.java @@ -0,0 +1,224 @@ +package com.salesmanager.core.business.modules.cms.content.gcp; + +import java.io.IOException; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import com.google.api.gax.paging.Page; +import com.google.cloud.storage.Blob; +import com.google.cloud.storage.BlobId; +import com.google.cloud.storage.BlobInfo; +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; +import com.google.cloud.storage.Blob.BlobSourceOption; +import com.google.cloud.storage.Storage.BlobField; +import com.google.cloud.storage.Storage.BucketGetOption; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.cms.content.ContentAssetsManager; +import com.salesmanager.core.business.modules.cms.impl.CMSManager; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.InputContentFile; +import com.salesmanager.core.model.content.OutputContentFile; + +/** + * Content management for a given retailer using GC{ (Google Cloud Platform) + * Cloud Storage with buckets + * + * + * Linux/ Mac export GOOGLE_APPLICATION_CREDENTIALS="/path/to/file" For Windows + * set GOOGLE_APPLICATION_CREDENTIALS="C:\path\to\file" + * + * following this article: https://www.baeldung.com/java-google-cloud-storage + * + * gsutil ls -L -b gs://shopizer-content + * + * + * @author carlsamson + * + */ +@Component("gcpContentAssetsManager") +public class GCPStaticContentAssetsManagerImpl implements ContentAssetsManager { + + private static final long serialVersionUID = 1L; + + private static final Logger LOGGER = LoggerFactory.getLogger(GCPStaticContentAssetsManagerImpl.class); + + @Autowired + @Qualifier("gcpAssetsManager") + private CMSManager cmsManager; + + @Override + public OutputContentFile getFile(String merchantStoreCode, Optional folderPath, FileContentType fileContentType, String contentName) + throws ServiceException { + try { + String bucketName = bucketName(); + // Instantiates a client + Storage storage = StorageOptions.getDefaultInstance().getService(); + + Blob blob = storage.get(BlobId.of(bucketName, nodePath(merchantStoreCode, fileContentType) + contentName)); + LOGGER.info("Content getFile"); + + return getOutputContentFile(blob.getContent(BlobSourceOption.generationMatch())); + + } catch (Exception e) { + LOGGER.error("Error while getting file", e); + throw new ServiceException(e); + } + } + + @Override + public List getFileNames(String merchantStoreCode, Optional folderPath, FileContentType fileContentType) + throws ServiceException { + try { + String bucketName = bucketName(); + Storage storage = StorageOptions.getDefaultInstance().getService(); + long bucketMetaGeneration = 42; + Bucket bucket = storage.get(bucketName, BucketGetOption.metagenerationMatch(bucketMetaGeneration)); + Page blobs = bucket.list(Storage.BlobListOption.prefix(nodePath(merchantStoreCode, fileContentType)), + Storage.BlobListOption.fields(BlobField.NAME)); + + List fileNames = new ArrayList(); + + for (Blob blob : blobs.iterateAll()) { + if (isInsideSubFolder(blob.getName())) + continue; + String mimetype = URLConnection.guessContentTypeFromName(blob.getName()); + if (!StringUtils.isBlank(mimetype)) { + fileNames.add(getName(blob.getName())); + } + + } + + LOGGER.info("Content get file names"); + return fileNames; + } catch (Exception e) { + LOGGER.error("Error while getting file names", e); + throw new ServiceException(e); + } + } + + @Override + public List getFiles(String merchantStoreCode, Optional folderPath, FileContentType fileContentType) + throws ServiceException { + try { + + List fileNames = getFileNames(merchantStoreCode, folderPath, fileContentType); + List files = new ArrayList(); + + for (String fileName : fileNames) { + files.add(getFile(merchantStoreCode, folderPath, fileContentType, fileName)); + } + + LOGGER.info("Content get file names"); + return files; + } catch (Exception e) { + LOGGER.error("Error while getting file names", e); + throw new ServiceException(e); + } + } + + @Override + public void addFile(String merchantStoreCode, Optional folderPath, InputContentFile inputStaticContentData) throws ServiceException { + + try { + LOGGER.debug("Adding file " + inputStaticContentData.getFileName()); + String bucketName = bucketName(); + + String nodePath = nodePath(merchantStoreCode, inputStaticContentData.getFileContentType()); + + Storage storage = StorageOptions.getDefaultInstance().getService(); + + BlobId blobId = BlobId.of(bucketName, nodePath + inputStaticContentData.getFileName()); + BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType(inputStaticContentData.getFileContentType().name()) + .build(); + byte[] targetArray = new byte[inputStaticContentData.getFile().available()]; + inputStaticContentData.getFile().read(targetArray); + storage.create(blobInfo, targetArray); + LOGGER.info("Content add file"); + } catch (IOException e) { + LOGGER.error("Error while adding file", e); + throw new ServiceException(e); + } + } + + @Override + public void addFiles(String merchantStoreCode, Optional folderPath, List inputStaticContentDataList) + throws ServiceException { + if (CollectionUtils.isNotEmpty(inputStaticContentDataList)) { + for (InputContentFile inputFile : inputStaticContentDataList) { + this.addFile(merchantStoreCode, folderPath, inputFile); + } + } + } + + @Override + public void removeFile(String merchantStoreCode, FileContentType staticContentType, String fileName, Optional folderPath) + throws ServiceException { + try { + String bucketName = bucketName(); + Storage storage = StorageOptions.getDefaultInstance().getService(); + storage.delete(bucketName, nodePath(merchantStoreCode, staticContentType) + fileName); + + LOGGER.info("Remove file"); + } catch (final Exception e) { + LOGGER.error("Error while removing file", e); + throw new ServiceException(e); + } + } + + @Override + public void removeFiles(String merchantStoreCode, Optional folderPath) throws ServiceException { + try { + // get buckets + String bucketName = bucketName(); + + Storage storage = StorageOptions.getDefaultInstance().getService(); + storage.delete(bucketName, nodePath(merchantStoreCode)); + + LOGGER.info("Remove folder"); + } catch (final Exception e) { + LOGGER.error("Error while removing folder", e); + throw new ServiceException(e); + } + } + + + public CMSManager getCmsManager() { + return cmsManager; + } + + public void setCmsManager(CMSManager cmsManager) { + this.cmsManager = cmsManager; + } + + + @Override + public void addFolder(String merchantStoreCode, String folderName, Optional folderPath) throws ServiceException { + // TODO Auto-generated method stub + + } + + @Override + public void removeFolder(String merchantStoreCode, String folderName, Optional folderPath) throws ServiceException { + // TODO Auto-generated method stub + + } + + @Override + public List listFolders(String merchantStoreCode, Optional folderPath) throws ServiceException { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/infinispan/CmsStaticContentFileManagerImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/infinispan/CmsStaticContentFileManagerImpl.java new file mode 100755 index 0000000000..34f36df473 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/infinispan/CmsStaticContentFileManagerImpl.java @@ -0,0 +1,477 @@ +/** + * + */ +package com.salesmanager.core.business.modules.cms.content.infinispan; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.net.FileNameMap; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import javax.annotation.PostConstruct; +import org.apache.commons.io.IOUtils; +import org.infinispan.tree.Fqn; +import org.infinispan.tree.Node; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.cms.content.ContentAssetsManager; +import com.salesmanager.core.business.modules.cms.impl.CMSManager; +import com.salesmanager.core.business.modules.cms.impl.CacheManager; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.InputContentFile; +import com.salesmanager.core.model.content.OutputContentFile; + +/** + * Manages - Images - Files (js, pdf, css...) on infinispan + * + * @author Umesh Awasthi + * @since 1.2 + * + */ +public class CmsStaticContentFileManagerImpl + // implements FilePut,FileGet,FileRemove + implements ContentAssetsManager { + + /** + * + */ + private static final long serialVersionUID = 1L; + private static final Logger LOGGER = LoggerFactory.getLogger(CmsStaticContentFileManagerImpl.class); + private static CmsStaticContentFileManagerImpl fileManager = null; + private static final String ROOT_NAME = "static-merchant-"; + + private String rootName = ROOT_NAME; + + private CacheManager cacheManager; + + public void stopFileManager() { + + try { + cacheManager.getManager().stop(); + LOGGER.info("Stopping CMS"); + } catch (final Exception e) { + LOGGER.error("Error while stopping CmsStaticContentFileManager", e); + } + } + + @PostConstruct + void init() { + + this.rootName = cacheManager.getRootName(); + LOGGER.info("init " + getClass().getName() + " setting root" + this.rootName); + + } + + public static CmsStaticContentFileManagerImpl getInstance() { + + if (fileManager == null) { + fileManager = new CmsStaticContentFileManagerImpl(); + } + + return fileManager; + + } + + /** + *

+ * Method to add static content data for given merchant.Static content data + * can be of following type + * + *

+	 * 1. CSS and JS files
+	 * 2. Digital Data like audio or video
+	 * 
+ *

+ *

+ * Merchant store code will be used to create cache node where merchant data + * will be stored,input data will contain name, file as well type of data + * being stored. + * + * @see FileContentType + *

+ * + * @param merchantStoreCode + * merchant store for whom data is being stored + * @param inputStaticContentData + * data object being stored + * @throws ServiceException + * + */ + @Override + public void addFile(final String merchantStoreCode, Optionalpath, final InputContentFile inputStaticContentData) + throws ServiceException { + if (cacheManager.getTreeCache() == null) { + LOGGER.error("Unable to find cacheManager.getTreeCache() in Infinispan.."); + throw new ServiceException( + "CmsStaticContentFileManagerInfinispanImpl has a null cacheManager.getTreeCache()"); + } + try { + + String nodePath = this.getNodePath(merchantStoreCode, inputStaticContentData.getFileContentType()); + + final Node merchantNode = this.getNode(nodePath); + + merchantNode.put(inputStaticContentData.getFileName(), + IOUtils.toByteArray(inputStaticContentData.getFile())); + + LOGGER.info("Content data added successfully."); + } catch (final Exception e) { + LOGGER.error("Error while saving static content data", e); + throw new ServiceException(e); + + } + + } + + /** + *

+ * Method to add files for given store.Files will be stored in Infinispan + * and will be retrieved based on the storeID. Following steps will be + * performed to store static content files + *

+ *
  • Merchant Node will be retrieved from the cacheTree if it exists else + * new node will be created.
  • + *
  • Files will be stored in StaticContentCacheAttribute , which + * eventually will be stored in Infinispan
  • + * + * @param merchantStoreCode + * Merchant store for which files are getting stored in + * Infinispan. + * @param inputStaticContentDataList + * input static content file list which will get + * {@link InputContentImage} stored + * @throws ServiceException + * if content file storing process fail. + * @see InputStaticContentData + * @see StaticContentCacheAttribute + */ + @Override + public void addFiles(final String merchantStoreCode, Optional path, final List inputStaticContentDataList) + throws ServiceException { + if (cacheManager.getTreeCache() == null) { + LOGGER.error("Unable to find cacheManager.getTreeCache() in Infinispan.."); + throw new ServiceException( + "CmsStaticContentFileManagerInfinispanImpl has a null cacheManager.getTreeCache()"); + } + try { + + for (final InputContentFile inputStaticContentData : inputStaticContentDataList) { + + String nodePath = this.getNodePath(merchantStoreCode, inputStaticContentData.getFileContentType()); + final Node merchantNode = this.getNode(nodePath); + merchantNode.put(inputStaticContentData.getFileName(), + IOUtils.toByteArray(inputStaticContentData.getFile())); + + } + + LOGGER.info("Total {} files added successfully.", inputStaticContentDataList.size()); + + } catch (final Exception e) { + LOGGER.error("Error while saving content image", e); + throw new ServiceException(e); + + } + } + + /** + * Method to return static data for given Merchant store based on the file + * name. Content data will be searched in underlying Infinispan cache tree + * and {@link OutputStaticContentData} will be returned on finding an + * associated file. In case of no file, null be returned. + * + * @param store + * Merchant store + * @param contentFileName + * name of file being requested + * @return {@link OutputStaticContentData} + * @throws ServiceException + */ + @Override + public OutputContentFile getFile(final String merchantStoreCode, Optional path, final FileContentType fileContentType, + final String contentFileName) throws ServiceException { + + if (cacheManager.getTreeCache() == null) { + throw new ServiceException("CmsStaticContentFileManagerInfinispan has a null cacheManager.getTreeCache()"); + } + OutputContentFile outputStaticContentData = new OutputContentFile(); + InputStream input = null; + try { + + String nodePath = this.getNodePath(merchantStoreCode, fileContentType); + + final Node merchantNode = this.getNode(nodePath); + + final byte[] fileBytes = (byte[]) merchantNode.get(contentFileName); + + if (fileBytes == null) { + LOGGER.warn("file byte is null, no file found"); + return null; + } + + input = new ByteArrayInputStream(fileBytes); + + final ByteArrayOutputStream output = new ByteArrayOutputStream(); + IOUtils.copy(input, output); + + outputStaticContentData.setFile(output); + outputStaticContentData.setMimeType(URLConnection.getFileNameMap().getContentTypeFor(contentFileName)); + outputStaticContentData.setFileName(contentFileName); + outputStaticContentData.setFileContentType(fileContentType); + + } catch (final Exception e) { + LOGGER.error("Error while fetching file for {} merchant ", merchantStoreCode); + throw new ServiceException(e); + } + return outputStaticContentData; + } + + @Override + public List getFiles(final String merchantStoreCode, Optional path, final FileContentType staticContentType) + throws ServiceException { + + if (cacheManager.getTreeCache() == null) { + throw new ServiceException("CmsStaticContentFileManagerInfinispan has a null cacheManager.getTreeCache()"); + } + List images = new ArrayList(); + try { + + FileNameMap fileNameMap = URLConnection.getFileNameMap(); + String nodePath = this.getNodePath(merchantStoreCode, staticContentType); + + final Node merchantNode = this.getNode(nodePath); + + for (String key : merchantNode.getKeys()) { + + byte[] imageBytes = (byte[]) merchantNode.get(key); + + OutputContentFile contentImage = new OutputContentFile(); + + InputStream input = new ByteArrayInputStream(imageBytes); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + IOUtils.copy(input, output); + + String contentType = fileNameMap.getContentTypeFor(key); + + contentImage.setFile(output); + contentImage.setMimeType(contentType); + contentImage.setFileName(key); + + images.add(contentImage); + + } + + } catch (final Exception e) { + LOGGER.error("Error while fetching file for {} merchant ", merchantStoreCode); + throw new ServiceException(e); + } + + return images; + + } + + @Override + public void removeFile(final String merchantStoreCode, final FileContentType staticContentType, + final String fileName, Optional path) throws ServiceException { + + if (cacheManager.getTreeCache() == null) { + throw new ServiceException("CmsStaticContentFileManagerInfinispan has a null cacheManager.getTreeCache()"); + } + + try { + + String nodePath = this.getNodePath(merchantStoreCode, staticContentType); + final Node merchantNode = this.getNode(nodePath); + + merchantNode.remove(fileName); + + } catch (final Exception e) { + LOGGER.error("Error while fetching file for {} merchant ", merchantStoreCode); + throw new ServiceException(e); + } + + } + + /** + * Removes the data in a given merchant node + */ + @SuppressWarnings("unchecked") + @Override + public void removeFiles(final String merchantStoreCode, Optional path) throws ServiceException { + + LOGGER.info("Removing all images for {} merchant ", merchantStoreCode); + if (cacheManager.getTreeCache() == null) { + LOGGER.error("Unable to find cacheManager.getTreeCache() in Infinispan.."); + throw new ServiceException("CmsImageFileManagerInfinispan has a null cacheManager.getTreeCache()"); + } + + try { + + final StringBuilder merchantPath = new StringBuilder(); + merchantPath.append(getRootName()).append(merchantStoreCode); + cacheManager.getTreeCache().getRoot().remove(merchantPath.toString()); + + } catch (final Exception e) { + LOGGER.error("Error while deleting content image for {} merchant ", merchantStoreCode); + throw new ServiceException(e); + } + + } + + @SuppressWarnings({ "unchecked" }) + private Node getNode(final String node) { + LOGGER.debug("Fetching node for store {} from Infinispan", node); + final StringBuilder merchantPath = new StringBuilder(); + merchantPath.append(getRootName()).append(node); + + Fqn contentFilesFqn = Fqn.fromString(merchantPath.toString()); + + Node nd = cacheManager.getTreeCache().getRoot().getChild(contentFilesFqn); + + if (nd == null) { + + cacheManager.getTreeCache().getRoot().addChild(contentFilesFqn); + nd = cacheManager.getTreeCache().getRoot().getChild(contentFilesFqn); + + } + + return nd; + + } + + private String getNodePath(final String storeCode, final FileContentType contentType) { + + StringBuilder nodePath = new StringBuilder(); + nodePath.append(storeCode).append("/").append(contentType.name()); + + return nodePath.toString(); + + } + + + /** + * Returns a folder path so it can be used as base node + * @param storeCode + * @param folder + * @return + */ + private String getFolder(final String storeCode, String folder) { + +/* StringBuilder nodePath = new StringBuilder(); + nodePath.append(storeCode).append("/").append(contentType.name()); + + return nodePath.toString();*/ + + + return null; + + } + + public CacheManager getCacheManager() { + return cacheManager; + } + + public void setCacheManager(CacheManager cacheManager) { + this.cacheManager = cacheManager; + } + + /** + * Queries the CMS to retrieve all static content files. Only the name of + * the file will be returned to the client + * + * @param merchantStoreCode + * @return + * @throws ServiceException + */ + @Override + public List getFileNames(final String merchantStoreCode, Optional path, final FileContentType staticContentType) + throws ServiceException { + + if (cacheManager.getTreeCache() == null) { + throw new ServiceException("CmsStaticContentFileManagerInfinispan has a null cacheManager.getTreeCache()"); + } + + try { + + String nodePath = this.getNodePath(merchantStoreCode, staticContentType); + final Node objectNode = this.getNode(nodePath); + + if (objectNode.getKeys().isEmpty()) { + LOGGER.warn("Unable to find content attribute for given merchant"); + return Collections.emptyList(); + } + return new ArrayList(objectNode.getKeys()); + + } catch (final Exception e) { + LOGGER.error("Error while fetching file for {} merchant ", merchantStoreCode); + throw new ServiceException(e); + } + + } + + public void setRootName(String rootName) { + this.rootName = rootName; + } + + public String getRootName() { + return rootName; + } + + @SuppressWarnings("unchecked") + @Override + public void addFolder(String merchantStoreCode, String folderName, Optional path) throws ServiceException { + + + String nodePath = this.getNodePath(merchantStoreCode, FileContentType.IMAGE); + + StringBuilder appender = new StringBuilder(); + appender.append(nodePath).append(Constants.SLASH); + + path.ifPresent(appender::append); + + + //Put logic in a method + + Fqn folderFqn = Fqn.fromString(appender.toString()); + + Node nd = cacheManager.getTreeCache().getRoot().getChild(folderFqn); + + if (nd == null) { + + cacheManager.getTreeCache().getRoot().addChild(folderFqn); + nd = cacheManager.getTreeCache().getRoot().getChild(folderFqn); + + } + + appender.append(Constants.SLASH).append(folderName); + + Fqn newFolderFqn = Fqn.fromString(appender.toString()); + cacheManager.getTreeCache().getRoot().addChild(newFolderFqn); + + } + + @Override + public void removeFolder(String merchantStoreCode, String folderName, Optional path) throws ServiceException { + // TODO Auto-generated method stub + + } + + @Override + public List listFolders(String merchantStoreCode, Optional path) throws ServiceException { + // TODO Auto-generated method stub + return null; + } + + @Override + public CMSManager getCmsManager() { + return null; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/local/CmsStaticContentFileManagerImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/local/CmsStaticContentFileManagerImpl.java new file mode 100755 index 0000000000..e973fff0eb --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/content/local/CmsStaticContentFileManagerImpl.java @@ -0,0 +1,484 @@ +/** + * + */ +package com.salesmanager.core.business.modules.cms.content.local; + +import java.io.IOException; +import java.net.URLConnection; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import javax.annotation.PostConstruct; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.cms.content.ContentAssetsManager; +import com.salesmanager.core.business.modules.cms.impl.CMSManager; +import com.salesmanager.core.business.modules.cms.impl.LocalCacheManagerImpl; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.InputContentFile; +import com.salesmanager.core.model.content.OutputContentFile; + +/** + * Manages - Images - Files (js, pdf, css...) on a local web server + * + * @author Carl Samson + * @since 1.0.3 + * + */ +public class CmsStaticContentFileManagerImpl implements ContentAssetsManager { + + /** + * + */ + private static final long serialVersionUID = 1L; + private static final Logger LOGGER = LoggerFactory.getLogger(CmsStaticContentFileManagerImpl.class); + private static CmsStaticContentFileManagerImpl fileManager = null; + private static final String ROOT_NAME = "static"; + + private static final String ROOT_CONTAINER = "files"; + + private String rootName = ROOT_NAME; + + private LocalCacheManagerImpl cacheManager; + + @PostConstruct + void init() { + + this.rootName = ((CMSManager) cacheManager).getRootName(); + LOGGER.info("init " + getClass().getName() + " setting root" + this.rootName); + + } + + public static CmsStaticContentFileManagerImpl getInstance() { + + if (fileManager == null) { + fileManager = new CmsStaticContentFileManagerImpl(); + } + + return fileManager; + + } + + /** + *

    + * Method to add static content data for given merchant.Static content data + * can be of following type + * + *

    +	 * 1. CSS and JS files
    +	 * 2. Digital Data like audio or video
    +	 * 
    + *

    + *

    + * Merchant store code will be used to create cache node where merchant data + * will be stored,input data will contain name, file as well type of data + * being stored. + * + * @see FileContentType + *

    + * + * @param merchantStoreCode + * merchant store for whom data is being stored + * @param inputStaticContentData + * data object being stored + * @throws ServiceException + * + */ + @Override + public void addFile(final String merchantStoreCode, Optional folderPath, + final InputContentFile inputStaticContentData) throws ServiceException { + /* + * if ( cacheManager.getTreeCache() == null ) { LOGGER.error( + * "Unable to find cacheManager.getTreeCache() in Infinispan.." ); throw + * new ServiceException( + * "CmsStaticContentFileManagerInfinispanImpl has a null cacheManager.getTreeCache()" + * ); } + */ + try { + + // base path + String rootPath = this.buildRootPath(); + Path confDir = Paths.get(rootPath); + this.createDirectoryIfNorExist(confDir); + + // node path + StringBuilder nodePath = new StringBuilder(); + nodePath.append(rootPath).append(merchantStoreCode); + Path merchantPath = Paths.get(nodePath.toString()); + this.createDirectoryIfNorExist(merchantPath); + + // file path + nodePath.append(Constants.SLASH).append(inputStaticContentData.getFileContentType()) + .append(Constants.SLASH); + Path dirPath = Paths.get(nodePath.toString()); + this.createDirectoryIfNorExist(dirPath); + + // folder path + + // file creation + nodePath.append(inputStaticContentData.getFileName()); + + Path path = Paths.get(nodePath.toString()); + + // file creation + // nodePath.append(Constants.SLASH).append(contentImage.getFileName()); + + // Path path = Paths.get(nodePath.toString()); + + Files.copy(inputStaticContentData.getFile(), path, StandardCopyOption.REPLACE_EXISTING); + + // String nodePath = this.getNodePath(merchantStoreCode, + // inputStaticContentData.getFileContentType()); + + // final Node merchantNode = this.getNode(nodePath); + + // merchantNode.put(inputStaticContentData.getFileName(), + // IOUtils.toByteArray( + // inputStaticContentData.getFile() )); + + LOGGER.info("Content data added successfully."); + } catch (final Exception e) { + LOGGER.error("Error while saving static content data", e); + throw new ServiceException(e); + + } + + } + + /** + *

    + * Method to add files for given store.Files will be stored in Infinispan + * and will be retrieved based on the storeID. Following steps will be + * performed to store static content files + *

    + *
  • Merchant Node will be retrieved from the cacheTree if it exists else + * new node will be created.
  • + *
  • Files will be stored in StaticContentCacheAttribute , which + * eventually will be stored in Infinispan
  • + * + * @param merchantStoreCode + * Merchant store for which files are getting stored in + * Infinispan. + * @param inputStaticContentDataList + * input static content file list which will get + * {@link InputContentImage} stored + * @throws ServiceException + * if content file storing process fail. + * @see InputStaticContentData + * @see StaticContentCacheAttribute + */ + @Override + public void addFiles(final String merchantStoreCode, Optional folderPath, + final List inputStaticContentDataList) throws ServiceException { + /* + * if ( cacheManager.getTreeCache() == null ) { LOGGER.error( + * "Unable to find cacheManager.getTreeCache() in Infinispan.." ); throw + * new ServiceException( + * "CmsStaticContentFileManagerInfinispanImpl has a null cacheManager.getTreeCache()" + * ); } + */ + try { + + // base path + String rootPath = this.buildRootPath(); + Path confDir = Paths.get(rootPath); + this.createDirectoryIfNorExist(confDir); + + // node path + StringBuilder nodePath = new StringBuilder(); + nodePath.append(rootPath).append(merchantStoreCode); + Path merchantPath = Paths.get(nodePath.toString()); + this.createDirectoryIfNorExist(merchantPath); + + for (final InputContentFile inputStaticContentData : inputStaticContentDataList) { + + // file path + nodePath.append(Constants.SLASH).append(inputStaticContentData.getFileContentType()) + .append(Constants.SLASH); + Path dirPath = Paths.get(nodePath.toString()); + this.createDirectoryIfNorExist(dirPath); + + // file creation + nodePath.append(Constants.SLASH).append(inputStaticContentData.getFileName()); + + Path path = Paths.get(nodePath.toString()); + + Files.copy(inputStaticContentData.getFile(), path, StandardCopyOption.REPLACE_EXISTING); + + // String nodePath = this.getNodePath(merchantStoreCode, + // inputStaticContentData.getFileContentType()); + + // final Node merchantNode = + // this.getNode(nodePath); + // merchantNode.put(inputStaticContentData.getFileName(), + // IOUtils.toByteArray( + // inputStaticContentData.getFile() )); + + } + + LOGGER.info("Total {} files added successfully.", inputStaticContentDataList.size()); + + } catch (final Exception e) { + LOGGER.error("Error while saving content image", e); + throw new ServiceException(e); + + } + } + + /** + * Method to return static data for given Merchant store based on the file + * name. Content data will be searched in underlying Infinispan cache tree + * and {@link OutputStaticContentData} will be returned on finding an + * associated file. In case of no file, null be returned. + * + * @param store + * Merchant store + * @param contentFileName + * name of file being requested + * @return {@link OutputStaticContentData} + * @throws ServiceException + */ + @Override + public OutputContentFile getFile(final String merchantStoreCode, Optional folderPath, + final FileContentType fileContentType, final String contentFileName) throws ServiceException { + + throw new ServiceException("Not implemented for httpd image manager"); + + } + + @Override + public List getFiles(final String merchantStoreCode, Optional folderPath, + final FileContentType staticContentType) throws ServiceException { + + throw new ServiceException("Not implemented for httpd image manager"); + + } + + @Override + public void removeFile(final String merchantStoreCode, final FileContentType staticContentType, + final String fileName, Optional folderPath) throws ServiceException { + + try { + + StringBuilder merchantPath = new StringBuilder(); + merchantPath.append(buildRootPath()).append(Constants.SLASH).append(merchantStoreCode) + .append(Constants.SLASH).append(staticContentType).append(Constants.SLASH).append(fileName); + + Path path = Paths.get(merchantPath.toString()); + + Files.deleteIfExists(path); + + } catch (final Exception e) { + LOGGER.error("Error while deleting files for {} merchant ", merchantStoreCode); + throw new ServiceException(e); + } + + } + + /** + * Removes the data in a given merchant node + */ + @Override + public void removeFiles(final String merchantStoreCode, Optional folderPath) throws ServiceException { + + LOGGER.debug("Removing all images for {} merchant ", merchantStoreCode); + + try { + + StringBuilder merchantPath = new StringBuilder(); + merchantPath.append(buildRootPath()).append(Constants.SLASH).append(merchantStoreCode); + + Path path = Paths.get(merchantPath.toString()); + + Files.deleteIfExists(path); + + } catch (final Exception e) { + LOGGER.error("Error while deleting content image for {} merchant ", merchantStoreCode); + throw new ServiceException(e); + } + + } + + /** + * Queries the CMS to retrieve all static content files. Only the name of + * the file will be returned to the client + * + * @param merchantStoreCode + * @return + * @throws ServiceException + */ + @Override + public List getFileNames(final String merchantStoreCode, Optional folderPath, + final FileContentType staticContentType) throws ServiceException { + + try { + + StringBuilder merchantPath = new StringBuilder(); + merchantPath.append(buildRootPath()).append(merchantStoreCode).append(Constants.SLASH) + .append(staticContentType); + + Path path = Paths.get(merchantPath.toString()); + + List fileNames = null; + + if (Files.exists(path)) { + + fileNames = new ArrayList(); + try (DirectoryStream directoryStream = Files.newDirectoryStream(path)) { + for (Path dirPath : directoryStream) { + + String fileName = dirPath.getFileName().toString(); + + if (staticContentType.name().equals(FileContentType.IMAGE.name())) { + // File f = new File(fileName); + String mimetype = URLConnection.guessContentTypeFromName(fileName); + // String mimetype= new + // MimetypesFileTypeMap().getContentType(f); + if (!StringUtils.isBlank(mimetype)) { + String type = mimetype.split("/")[0]; + if (type.equals("image")) { + fileNames.add(fileName); + } + } + // fileNames.add(fileName); + + } else { + fileNames.add(fileName); + } + + } + } + + return fileNames; + } + } catch (final Exception e) { + LOGGER.error("Error while fetching file for {} merchant ", merchantStoreCode); + throw new ServiceException(e); + } + return new ArrayList<>(); + } + + public void setRootName(String rootName) { + this.rootName = rootName; + } + + public String getRootName() { + return rootName; + } + + private String buildRootPath() { + return new StringBuilder().append(getRootName()).append(Constants.SLASH).append(ROOT_CONTAINER) + .append(Constants.SLASH).toString(); + + } + + private void createDirectoryIfNorExist(Path path) throws IOException { + + if (Files.notExists(path)) { + Files.createDirectory(path); + } + } + + public LocalCacheManagerImpl getCacheManager() { + return cacheManager; + } + + public void setCacheManager(LocalCacheManagerImpl cacheManager) { + this.cacheManager = cacheManager; + } + + @Override + public void addFolder(String merchantStoreCode, String folderName, Optional folderPath) + throws ServiceException { + + + try { + + Path merchantPath = this.buildMerchantPath(merchantStoreCode); + + StringBuilder nodePath = new StringBuilder(); + if(folderPath.isPresent()) { + nodePath + .append(merchantPath.toString()) + .append(Constants.SLASH).append(folderPath.get()).append(Constants.SLASH); + } + // add folder + nodePath.append(folderName); + + Path dirPath = Paths.get(nodePath.toString()); + this.createDirectoryIfNorExist(dirPath); + + } catch (IOException e) { + LOGGER.error("Error while creating fiolder for {} merchant ", merchantStoreCode); + throw new ServiceException(e); + } + + } + + private Path buildMerchantPath(String merchantCode) throws IOException { + + String rootPath = this.buildRootPath(); + Path confDir = Paths.get(rootPath); + + // node path + StringBuilder nodePath = new StringBuilder(); + nodePath + .append(confDir.toString()) + .append(rootPath).append(merchantCode); + Path merchantPath = Paths.get(nodePath.toString()); + this.createDirectoryIfNorExist(merchantPath); + + return merchantPath; + + } + + @Override + public void removeFolder(String merchantStoreCode, String folderName, Optional folderPath) + throws ServiceException { + + //String rootPath = this.buildRootPath(); + try { + + Path merchantPath = this.buildMerchantPath(merchantStoreCode); + StringBuilder nodePath = new StringBuilder(); + nodePath.append(merchantPath.toString()).append(Constants.SLASH); + if(folderPath.isPresent()) { + nodePath.append(folderPath.get()).append(Constants.SLASH); + } + + nodePath.append(folderName); + + Path longPath = Paths.get(nodePath.toString()); + + if (Files.exists(longPath)) { + Files.delete(longPath); + } + + } catch (IOException e) { + LOGGER.error("Error while creating fiolder for {} merchant ", merchantStoreCode); + throw new ServiceException(e); + } + + } + + @Override + public List listFolders(String merchantStoreCode, Optional folderPath) throws ServiceException { + // TODO Auto-generated method stub + return null; + } + + @Override + public CMSManager getCmsManager() { + return null; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/CMSManager.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/CMSManager.java new file mode 100755 index 0000000000..54a7f2dd63 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/CMSManager.java @@ -0,0 +1,15 @@ +package com.salesmanager.core.business.modules.cms.impl; + +/** + * Marker interface + * + * @author carlsamson + * + */ +public interface CMSManager { + + String getRootName(); + + String getLocation(); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/CacheManager.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/CacheManager.java new file mode 100755 index 0000000000..b7dd7c4461 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/CacheManager.java @@ -0,0 +1,13 @@ +package com.salesmanager.core.business.modules.cms.impl; + +import org.infinispan.manager.EmbeddedCacheManager; +import org.infinispan.tree.TreeCache; + +public interface CacheManager extends CMSManager { + + EmbeddedCacheManager getManager(); + + @SuppressWarnings("rawtypes") + TreeCache getTreeCache(); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/CacheManagerImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/CacheManagerImpl.java new file mode 100755 index 0000000000..79a94e0b2b --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/CacheManagerImpl.java @@ -0,0 +1,95 @@ +package com.salesmanager.core.business.modules.cms.impl; + +import org.infinispan.Cache; +import org.infinispan.configuration.cache.Configuration; +import org.infinispan.configuration.cache.ConfigurationBuilder; +import org.infinispan.manager.EmbeddedCacheManager; +import org.infinispan.tree.TreeCache; +import org.infinispan.tree.TreeCacheFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class CacheManagerImpl implements CacheManager { + + private static final Logger LOGGER = LoggerFactory.getLogger(CacheManagerImpl.class); + + //private static final String LOCATION_PROPERTIES = "location"; + + protected String location = null; + + @SuppressWarnings("rawtypes") + private TreeCache treeCache = null; + + @SuppressWarnings("unchecked") + protected void init(String namedCache, String locationFolder) { + + + try { + + this.location = locationFolder; + // manager = new DefaultCacheManager(repositoryFileName); + + VendorCacheManager manager = VendorCacheManager.getInstance(); + + if (manager == null) { + LOGGER.error("CacheManager is null"); + return; + } + + TreeCacheFactory f = null; + + +/* @SuppressWarnings("rawtypes") + Cache c = manager.getManager().getCache(namedCache); + + if(c != null) { + f = new TreeCacheFactory(); + treeCache = f.createTreeCache(c); + //this.treeCache = (TreeCache)c; + return; + }*/ + + + Configuration config = new ConfigurationBuilder() + .persistence().passivation(false) + .addSingleFileStore() + .segmented(false) + .location(location).async().enable() + .preload(false).shared(false) + .invocationBatching().enable() + .build(); + + manager.getManager().defineConfiguration(namedCache, config); + + final Cache cache = manager.getManager().getCache(namedCache); + + f = new TreeCacheFactory(); + treeCache = f.createTreeCache(cache); + cache.start(); + + LOGGER.debug("CMS started"); + + + + } catch (Exception e) { + LOGGER.error("Error while instantiating CmsImageFileManager", e); + } finally { + + } + + + + } + + public EmbeddedCacheManager getManager() { + return VendorCacheManager.getInstance().getManager(); + } + + @SuppressWarnings("rawtypes") + public TreeCache getTreeCache() { + return treeCache; + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/DownloadCacheManagerImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/DownloadCacheManagerImpl.java new file mode 100644 index 0000000000..b4ebe47f74 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/DownloadCacheManagerImpl.java @@ -0,0 +1,36 @@ +package com.salesmanager.core.business.modules.cms.impl; + +/** + * Infinispan asset manager for download files + * + * @author casams1 + * + */ +public class DownloadCacheManagerImpl extends CacheManagerImpl { + + + private final static String NAMED_CACHE = "DownlaodRepository"; + private String root; + + + public DownloadCacheManagerImpl(String location, String root) { + super.init(NAMED_CACHE, location); + this.root = root; + } + + + @Override + public String getRootName() { + return root; + } + + + @Override + public String getLocation() { + return location; + } + + + +} + diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/GCPCacheManagerImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/GCPCacheManagerImpl.java new file mode 100755 index 0000000000..3d09678409 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/GCPCacheManagerImpl.java @@ -0,0 +1,47 @@ +package com.salesmanager.core.business.modules.cms.impl; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * Interaction with GCP (Google Cloud Platform) with AWS S3 + * https://cloud.google.com/storage/docs/uploading-objects#storage-upload-object-java + * + * @author carlsamson + * + */ +@Component("gcpAssetsManager") +public class GCPCacheManagerImpl implements CMSManager { + + @Value("${config.cms.gcp.bucket}") + private String bucketName; + + + + public GCPCacheManagerImpl() {} + + + @Override + public String getRootName() { + return bucketName; + } + + public String getBucketName() { + return bucketName; + } + + + @Override + public String getLocation() { + // TODO Auto-generated method stub + return null; + } + + public void setBucketName(String bucketName) { + this.bucketName = bucketName; + } + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/LocalCacheManagerImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/LocalCacheManagerImpl.java new file mode 100755 index 0000000000..a1f0ce45df --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/LocalCacheManagerImpl.java @@ -0,0 +1,29 @@ +package com.salesmanager.core.business.modules.cms.impl; + +/** + * Http server bootstrap + * + * @author carlsamson + * + */ +public class LocalCacheManagerImpl implements CMSManager { + + private String rootName;// file location root + + public LocalCacheManagerImpl(String rootName) { + this.rootName = rootName; + } + + + @Override + public String getRootName() { + return rootName; + } + + @Override + public String getLocation() { + return ""; + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/S3CacheManagerImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/S3CacheManagerImpl.java new file mode 100755 index 0000000000..9f34047331 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/S3CacheManagerImpl.java @@ -0,0 +1,42 @@ +package com.salesmanager.core.business.modules.cms.impl; + +/** + * Interaction with AWS S3 + * https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/examples-s3-transfermanager.html + * + * @author carlsamson + * + */ +public class S3CacheManagerImpl implements CMSManager { + + + private String bucketName; + private String regionName; + + public S3CacheManagerImpl(String bucketName, String regionName) { + this.bucketName = bucketName; + this.regionName = regionName; + } + + + @Override + public String getRootName() { + return bucketName; + } + + @Override + public String getLocation() { + return regionName; + } + + + public String getBucketName() { + return bucketName; + } + + public String getRegionName() { + return regionName; + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/StaticContentCacheManagerImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/StaticContentCacheManagerImpl.java new file mode 100755 index 0000000000..05170eb023 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/StaticContentCacheManagerImpl.java @@ -0,0 +1,44 @@ +/** + * + */ +package com.salesmanager.core.business.modules.cms.impl; + +/** + * Cache manager to handle static content data in Infinispan cache. static content data can be of + * following type + * + *
    + * 1. CSS files.
    + * 2. JS Files.
    + * 3. Digital Data.
    + * 
    + * + * @author Umesh Awasthi + * @version 1.2 + * + * + */ +public class StaticContentCacheManagerImpl extends CacheManagerImpl { + + private final static String NAMED_CACHE = "FilesRepository"; + + private String location = null; + private String root = null; + + + public StaticContentCacheManagerImpl(String location, String root) { + + super.init(NAMED_CACHE, location); + this.location = location; + this.root = root; + } + + public String getLocation() { + return location; + } + + @Override + public String getRootName() { + return root; + } +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/StoreCacheManagerImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/StoreCacheManagerImpl.java new file mode 100755 index 0000000000..72d5cbda74 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/StoreCacheManagerImpl.java @@ -0,0 +1,36 @@ +package com.salesmanager.core.business.modules.cms.impl; + +/** + * Infinispan asset manager + * + * @author casams1 + * + */ +public class StoreCacheManagerImpl extends CacheManagerImpl { + + + private final static String NAMED_CACHE = "StoreRepository"; + private String root; + + + public StoreCacheManagerImpl(String location, String root) { + super.init(NAMED_CACHE, location); + this.root = root; + } + + + @Override + public String getRootName() { + return root; + } + + + @Override + public String getLocation() { + return location; + } + + + +} + diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/VendorCacheManager.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/VendorCacheManager.java new file mode 100755 index 0000000000..fecbba17f6 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/impl/VendorCacheManager.java @@ -0,0 +1,39 @@ +package com.salesmanager.core.business.modules.cms.impl; + +import org.infinispan.manager.DefaultCacheManager; +import org.infinispan.manager.EmbeddedCacheManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VendorCacheManager { + + private static final Logger LOGGER = LoggerFactory.getLogger(VendorCacheManager.class); + private EmbeddedCacheManager manager = null; + private static VendorCacheManager vendorCacheManager = null; + + + private VendorCacheManager() { + + try { + manager = new DefaultCacheManager(); + } catch (Exception e) { + LOGGER.error("Cannot start manager " + e.toString()); + } + + } + + + public static VendorCacheManager getInstance() { + if (vendorCacheManager == null) { + vendorCacheManager = new VendorCacheManager(); + + } + return vendorCacheManager; + } + + + public EmbeddedCacheManager getManager() { + return manager; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductAssetsManager.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductAssetsManager.java new file mode 100755 index 0000000000..339e0ece05 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductAssetsManager.java @@ -0,0 +1,9 @@ +package com.salesmanager.core.business.modules.cms.product; + +import java.io.Serializable; +import com.salesmanager.core.business.modules.cms.common.AssetsManager; + +public interface ProductAssetsManager + extends AssetsManager, ProductImageGet, ProductImagePut, ProductImageRemove, Serializable { + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductFileManager.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductFileManager.java new file mode 100755 index 0000000000..212ff3d8c7 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductFileManager.java @@ -0,0 +1,10 @@ +package com.salesmanager.core.business.modules.cms.product; + + + +public abstract class ProductFileManager + implements ProductImagePut, ProductImageGet, ProductImageRemove { + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductFileManagerImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductFileManagerImpl.java new file mode 100755 index 0000000000..70d0a2c08f --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductFileManagerImpl.java @@ -0,0 +1,366 @@ +package com.salesmanager.core.business.modules.cms.product; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.net.FileNameMap; +import java.net.URLConnection; +import java.util.List; +import javax.imageio.ImageIO; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.utils.CoreConfiguration; +import com.salesmanager.core.business.utils.ProductImageCropUtils; +import com.salesmanager.core.business.utils.ProductImageSizeUtils; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.file.ProductImageSize; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.ImageContentFile; +import com.salesmanager.core.model.content.OutputContentFile; + + +public class ProductFileManagerImpl extends ProductFileManager { + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductFileManagerImpl.class); + + + private ProductImagePut uploadImage; + private ProductImageGet getImage; + private ProductImageRemove removeImage; + + private CoreConfiguration configuration; + + private final static String PRODUCT_IMAGE_HEIGHT_SIZE = "PRODUCT_IMAGE_HEIGHT_SIZE"; + private final static String PRODUCT_IMAGE_WIDTH_SIZE = "PRODUCT_IMAGE_WIDTH_SIZE"; + private final static String CROP_UPLOADED_IMAGES = "CROP_UPLOADED_IMAGES"; + + + public CoreConfiguration getConfiguration() { + return configuration; + } + + + public void setConfiguration(CoreConfiguration configuration) { + this.configuration = configuration; + } + + + public ProductImageRemove getRemoveImage() { + return removeImage; + } + + + public void setRemoveImage(ProductImageRemove removeImage) { + this.removeImage = removeImage; + } + + + public void addProductImage(ProductImage productImage, ImageContentFile contentImage) + throws ServiceException { + + + try { + + /** copy to input stream **/ + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + // Fake code simulating the copy + // You can generally do better with nio if you need... + // And please, unlike me, do something about the Exceptions :D + byte[] buffer = new byte[1024]; + int len; + while ((len = contentImage.getFile().read(buffer)) > -1) { + baos.write(buffer, 0, len); + } + baos.flush(); + + // Open new InputStreams using the recorded bytes + // Can be repeated as many times as you wish + InputStream is1 = new ByteArrayInputStream(baos.toByteArray()); + InputStream is2 = new ByteArrayInputStream(baos.toByteArray()); + + BufferedImage bufferedImage = ImageIO.read(is2); + + + if (bufferedImage == null) { + LOGGER.error("Cannot read image format for " + productImage.getProductImage()); + throw new Exception("Cannot read image format " + productImage.getProductImage()); + } + + // contentImage.setBufferedImage(bufferedImage); + contentImage.setFile(is1); + + + // upload original -- L + contentImage.setFileContentType(FileContentType.PRODUCTLG); + uploadImage.addProductImage(productImage, contentImage); + + /* + * //default large InputContentImage largeContentImage = new + * InputContentImage(ImageContentType.PRODUCT); + * largeContentImage.setFile(contentImage.getFile()); + * largeContentImage.setDefaultImage(productImage.isDefaultImage()); + * largeContentImage.setImageName(new + * StringBuilder().append("L-").append(productImage.getProductImage()).toString()); + * + * + * uploadImage.uploadProductImage(configuration, productImage, largeContentImage); + */ + + /* + * //default small InputContentImage smallContentImage = new + * InputContentImage(ImageContentType.PRODUCT); + * smallContentImage.setFile(contentImage.getFile()); + * smallContentImage.setDefaultImage(productImage.isDefaultImage()); + * smallContentImage.setImageName(new + * StringBuilder().append("S-").append(productImage.getProductImage()).toString()); + * + * uploadImage.uploadProductImage(configuration, productImage, smallContentImage); + */ + + + // get template properties file + + String slargeImageHeight = configuration.getProperty(PRODUCT_IMAGE_HEIGHT_SIZE); + String slargeImageWidth = configuration.getProperty(PRODUCT_IMAGE_WIDTH_SIZE); + + // String ssmallImageHeight = configuration.getProperty("SMALL_IMAGE_HEIGHT_SIZE"); + // String ssmallImageWidth = configuration.getProperty("SMALL_IMAGE_WIDTH_SIZE"); + + //Resizes + if (!StringUtils.isBlank(slargeImageHeight) && !StringUtils.isBlank(slargeImageWidth)) { // && + // !StringUtils.isBlank(ssmallImageHeight) + // && + // !StringUtils.isBlank(ssmallImageWidth)) + // { + + + FileNameMap fileNameMap = URLConnection.getFileNameMap(); + + String contentType = fileNameMap.getContentTypeFor(contentImage.getFileName()); + String extension = null; + if (contentType != null) { + extension = contentType.substring(contentType.indexOf('/') + 1, contentType.length()); + } + + if (extension == null) { + extension = "jpeg"; + } + + + int largeImageHeight = Integer.parseInt(slargeImageHeight); + int largeImageWidth = Integer.parseInt(slargeImageWidth); + + if (largeImageHeight <= 0 || largeImageWidth <= 0) { + String sizeMsg = + "Image configuration set to an invalid value [PRODUCT_IMAGE_HEIGHT_SIZE] " + + largeImageHeight + " , [PRODUCT_IMAGE_WIDTH_SIZE] " + largeImageWidth; + LOGGER.error(sizeMsg); + throw new ServiceException(sizeMsg); + } + + if (!StringUtils.isBlank(configuration.getProperty(CROP_UPLOADED_IMAGES)) + && configuration.getProperty(CROP_UPLOADED_IMAGES).equals(Constants.TRUE)) { + // crop image + ProductImageCropUtils utils = + new ProductImageCropUtils(bufferedImage, largeImageWidth, largeImageHeight); + if (utils.isCropeable()) { + bufferedImage = utils.getCroppedImage(); + } + } + + // do not keep a large image for now, just take care of the regular image and a small image + + // resize large + // ByteArrayOutputStream output = new ByteArrayOutputStream(); + BufferedImage largeResizedImage; + if(bufferedImage.getWidth() > largeImageWidth ||bufferedImage.getHeight() > largeImageHeight) { + largeResizedImage = ProductImageSizeUtils.resizeWithRatio(bufferedImage, largeImageWidth, largeImageHeight); + } else { + largeResizedImage = bufferedImage; + } + + + File tempLarge = + File.createTempFile(new StringBuilder().append(productImage.getProduct().getId()) + .append("tmpLarge").toString(), "." + extension); + ImageIO.write(largeResizedImage, extension, tempLarge); + + try(FileInputStream isLarge = new FileInputStream(tempLarge)) { + + + // IOUtils.copy(isLarge, output); + + + ImageContentFile largeContentImage = new ImageContentFile(); + largeContentImage.setFileContentType(FileContentType.PRODUCT); + largeContentImage.setFileName(productImage.getProductImage()); + largeContentImage.setFile(isLarge); + + + // largeContentImage.setBufferedImage(bufferedImage); + + // largeContentImage.setFile(output); + // largeContentImage.setDefaultImage(false); + // largeContentImage.setImageName(new + // StringBuilder().append("L-").append(productImage.getProductImage()).toString()); + + + uploadImage.addProductImage(productImage, largeContentImage); + + // output.flush(); + // output.close(); + + tempLarge.delete(); + + // now upload original + + + + /* + * //resize small BufferedImage smallResizedImage = ProductImageSizeUtils.resize(cropped, + * smallImageWidth, smallImageHeight); File tempSmall = File.createTempFile(new + * StringBuilder().append(productImage.getProduct().getId()).append("tmpSmall").toString(), + * "." + extension ); ImageIO.write(smallResizedImage, extension, tempSmall); + * + * //byte[] is = IOUtils.toByteArray(new FileInputStream(tempSmall)); + * + * FileInputStream isSmall = new FileInputStream(tempSmall); + * + * output = new ByteArrayOutputStream(); IOUtils.copy(isSmall, output); + * + * + * smallContentImage = new InputContentImage(ImageContentType.PRODUCT); + * smallContentImage.setFile(output); smallContentImage.setDefaultImage(false); + * smallContentImage.setImageName(new + * StringBuilder().append("S-").append(productImage.getProductImage()).toString()); + * + * uploadImage.uploadProductImage(configuration, productImage, smallContentImage); + * + * output.flush(); output.close(); + * + * tempSmall.delete(); + */ + + + } + } else { + // small will be the same as the original + contentImage.setFileContentType(FileContentType.PRODUCT); + uploadImage.addProductImage(productImage, contentImage); + } + + + + } catch (Exception e) { + throw new ServiceException(e); + } finally { + try { + productImage.getImage().close(); + } catch (Exception ignore) { + } + } + + } + + + public OutputContentFile getProductImage(ProductImage productImage) throws ServiceException { + // will return original + return getImage.getProductImage(productImage); + } + + + @Override + public List getImages(final String merchantStoreCode, + FileContentType imageContentType) throws ServiceException { + // will return original + return getImage.getImages(merchantStoreCode, FileContentType.PRODUCT); + } + + @Override + public List getImages(Product product) throws ServiceException { + return getImage.getImages(product); + } + + + + @Override + public void removeProductImage(ProductImage productImage) throws ServiceException { + + this.removeImage.removeProductImage(productImage); + + /* + * ProductImage large = new ProductImage(); large.setProduct(productImage.getProduct()); + * large.setProductImage("L" + productImage.getProductImage()); + * + * this.removeImage.removeProductImage(large); + * + * ProductImage small = new ProductImage(); small.setProduct(productImage.getProduct()); + * small.setProductImage("S" + productImage.getProductImage()); + * + * this.removeImage.removeProductImage(small); + */ + + } + + + @Override + public void removeProductImages(Product product) throws ServiceException { + + this.removeImage.removeProductImages(product); + + } + + + @Override + public void removeImages(final String merchantStoreCode) throws ServiceException { + + this.removeImage.removeImages(merchantStoreCode); + + } + + + public ProductImagePut getUploadImage() { + return uploadImage; + } + + + public void setUploadImage(ProductImagePut uploadImage) { + this.uploadImage = uploadImage; + } + + + + public ProductImageGet getGetImage() { + return getImage; + } + + + public void setGetImage(ProductImageGet getImage) { + this.getImage = getImage; + } + + + @Override + public OutputContentFile getProductImage(String merchantStoreCode, String productCode, + String imageName) throws ServiceException { + return getImage.getProductImage(merchantStoreCode, productCode, imageName); + } + + + + @Override + public OutputContentFile getProductImage(String merchantStoreCode, String productCode, + String imageName, ProductImageSize size) throws ServiceException { + return getImage.getProductImage(merchantStoreCode, productCode, imageName, size); + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductImageGet.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductImageGet.java new file mode 100755 index 0000000000..4d6cf03605 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductImageGet.java @@ -0,0 +1,33 @@ +package com.salesmanager.core.business.modules.cms.product; + +import java.util.List; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.cms.common.ImageGet; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.file.ProductImageSize; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.content.OutputContentFile; + +public interface ProductImageGet extends ImageGet { + + /** + * Used for accessing the path directly + * + * @param merchantStoreCode + * @param product + * @param imageName + * @return + * @throws ServiceException + */ + OutputContentFile getProductImage(final String merchantStoreCode, final String productCode, + final String imageName) throws ServiceException; + + OutputContentFile getProductImage(final String merchantStoreCode, final String productCode, + final String imageName, final ProductImageSize size) throws ServiceException; + + OutputContentFile getProductImage(ProductImage productImage) throws ServiceException; + + List getImages(Product product) throws ServiceException; + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductImagePut.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductImagePut.java new file mode 100755 index 0000000000..00a54972e4 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductImagePut.java @@ -0,0 +1,13 @@ +package com.salesmanager.core.business.modules.cms.product; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.content.ImageContentFile; + + +public interface ProductImagePut { + + void addProductImage(ProductImage productImage, ImageContentFile contentImage) + throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductImageRemove.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductImageRemove.java new file mode 100755 index 0000000000..c500a3fe63 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/ProductImageRemove.java @@ -0,0 +1,15 @@ +package com.salesmanager.core.business.modules.cms.product; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.cms.common.ImageRemove; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.image.ProductImage; + + +public interface ProductImageRemove extends ImageRemove { + + void removeProductImage(ProductImage productImage) throws ServiceException; + + void removeProductImages(Product product) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/aws/S3ProductContentFileManager.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/aws/S3ProductContentFileManager.java new file mode 100755 index 0000000000..ecd597f38c --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/aws/S3ProductContentFileManager.java @@ -0,0 +1,362 @@ +package com.salesmanager.core.business.modules.cms.product.aws; + +import java.io.ByteArrayOutputStream; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import com.amazonaws.services.s3.model.AmazonS3Exception; +import com.amazonaws.services.s3.model.Bucket; +import com.amazonaws.services.s3.model.CannedAccessControlList; +import com.amazonaws.services.s3.model.ListObjectsV2Request; +import com.amazonaws.services.s3.model.ListObjectsV2Result; +import com.amazonaws.services.s3.model.ObjectMetadata; +import com.amazonaws.services.s3.model.PutObjectRequest; +import com.amazonaws.services.s3.model.S3Object; +import com.amazonaws.services.s3.model.S3ObjectSummary; +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.cms.impl.CMSManager; +import com.salesmanager.core.business.modules.cms.product.ProductAssetsManager; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.file.ProductImageSize; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.ImageContentFile; +import com.salesmanager.core.model.content.OutputContentFile; + +/** + * Product content file manager with AWS S3 + * + * @author carlsamson + * + */ +public class S3ProductContentFileManager + implements ProductAssetsManager { + + /** + * + */ + private static final long serialVersionUID = 1L; + + + + private static final Logger LOGGER = LoggerFactory.getLogger(S3ProductContentFileManager.class); + + + + private static S3ProductContentFileManager fileManager = null; + + private static String DEFAULT_BUCKET_NAME = "shopizer-content"; + private static String DEFAULT_REGION_NAME = "us-east-1"; + private static final String ROOT_NAME = "products"; + + private static final char UNIX_SEPARATOR = '/'; + private static final char WINDOWS_SEPARATOR = '\\'; + + + private final static String SMALL = "SMALL"; + private final static String LARGE = "LARGE"; + + private CMSManager cmsManager; + + public static S3ProductContentFileManager getInstance() { + + if (fileManager == null) { + fileManager = new S3ProductContentFileManager(); + } + + return fileManager; + + } + + @Override + public List getImages(String merchantStoreCode, + FileContentType imageContentType) throws ServiceException { + try { + // get buckets + String bucketName = bucketName(); + + + + ListObjectsV2Request listObjectsRequest = new ListObjectsV2Request() + .withBucketName(bucketName).withPrefix(nodePath(merchantStoreCode)); + + List files = null; + final AmazonS3 s3 = s3Client(); + ListObjectsV2Result results = s3.listObjectsV2(listObjectsRequest); + List objects = results.getObjectSummaries(); + for (S3ObjectSummary os : objects) { + if (files == null) { + files = new ArrayList(); + } + String mimetype = URLConnection.guessContentTypeFromName(os.getKey()); + if (!StringUtils.isBlank(mimetype)) { + S3Object o = s3.getObject(bucketName, os.getKey()); + byte[] byteArray = IOUtils.toByteArray(o.getObjectContent()); + ByteArrayOutputStream baos = new ByteArrayOutputStream(byteArray.length); + baos.write(byteArray, 0, byteArray.length); + OutputContentFile ct = new OutputContentFile(); + ct.setFile(baos); + files.add(ct); + } + } + + return files; + } catch (final Exception e) { + LOGGER.error("Error while getting files", e); + throw new ServiceException(e); + + } + } + + @Override + public void removeImages(String merchantStoreCode) throws ServiceException { + try { + // get buckets + String bucketName = bucketName(); + + final AmazonS3 s3 = s3Client(); + s3.deleteObject(bucketName, nodePath(merchantStoreCode)); + + LOGGER.info("Remove folder"); + } catch (final Exception e) { + LOGGER.error("Error while removing folder", e); + throw new ServiceException(e); + + } + + } + + @Override + public void removeProductImage(ProductImage productImage) throws ServiceException { + try { + // get buckets + String bucketName = bucketName(); + + final AmazonS3 s3 = s3Client(); + s3.deleteObject(bucketName, nodePath(productImage.getProduct().getMerchantStore().getCode(), + productImage.getProduct().getSku()) + productImage.getProductImage()); + + LOGGER.info("Remove file"); + } catch (final Exception e) { + LOGGER.error("Error while removing file", e); + throw new ServiceException(e); + + } + + } + + @Override + public void removeProductImages(Product product) throws ServiceException { + try { + // get buckets + String bucketName = bucketName(); + + final AmazonS3 s3 = s3Client(); + s3.deleteObject(bucketName, nodePath(product.getMerchantStore().getCode(), product.getSku())); + + LOGGER.info("Remove file"); + } catch (final Exception e) { + LOGGER.error("Error while removing file", e); + throw new ServiceException(e); + + } + + } + + @Override + public OutputContentFile getProductImage(String merchantStoreCode, String productCode, + String imageName) throws ServiceException { + // TODO Auto-generated method stub + return null; + } + + @Override + public OutputContentFile getProductImage(String merchantStoreCode, String productCode, + String imageName, ProductImageSize size) throws ServiceException { + // TODO Auto-generated method stub + return null; + } + + @Override + public OutputContentFile getProductImage(ProductImage productImage) throws ServiceException { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getImages(Product product) throws ServiceException { + return null; + } + + @Override + public void addProductImage(ProductImage productImage, ImageContentFile contentImage) + throws ServiceException { + + + try { + // get buckets + String bucketName = bucketName(); + final AmazonS3 s3 = s3Client(); + + String nodePath = this.nodePath(productImage.getProduct().getMerchantStore().getCode(), + productImage.getProduct().getSku(), contentImage); + + + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentType(contentImage.getMimeType()); + + PutObjectRequest request = new PutObjectRequest(bucketName, + nodePath + productImage.getProductImage(), contentImage.getFile(), metadata); + request.setCannedAcl(CannedAccessControlList.PublicRead); + + + s3.putObject(request); + + + LOGGER.info("Product add file"); + + } catch (final Exception e) { + LOGGER.error("Error while removing file", e); + throw new ServiceException(e); + + } + + + } + + + private Bucket getBucket(String bucket_name) { + final AmazonS3 s3 = s3Client(); + Bucket named_bucket = null; + List buckets = s3.listBuckets(); + for (Bucket b : buckets) { + if (b.getName().equals(bucket_name)) { + named_bucket = b; + } + } + + if (named_bucket == null) { + named_bucket = createBucket(bucket_name); + } + + return named_bucket; + } + + private Bucket createBucket(String bucket_name) { + final AmazonS3 s3 = s3Client(); + Bucket b = null; + if (s3.doesBucketExistV2(bucket_name)) { + System.out.format("Bucket %s already exists.\n", bucket_name); + b = getBucket(bucket_name); + } else { + try { + b = s3.createBucket(bucket_name); + } catch (AmazonS3Exception e) { + System.err.println(e.getErrorMessage()); + } + } + return b; + } + + /** + * Builds an amazon S3 client + * + * @return + */ + private AmazonS3 s3Client() { + + return AmazonS3ClientBuilder.standard().withRegion(regionName()) // The first region to + // try your request + // against + .build(); + } + + private String bucketName() { + String bucketName = getCmsManager().getRootName(); + if (StringUtils.isBlank(bucketName)) { + bucketName = DEFAULT_BUCKET_NAME; + } + return bucketName; + } + + private String regionName() { + String regionName = getCmsManager().getLocation(); + if (StringUtils.isBlank(regionName)) { + regionName = DEFAULT_REGION_NAME; + } + return regionName; + } + + private String nodePath(String store) { + return new StringBuilder().append(ROOT_NAME).append(Constants.SLASH).append(store) + .append(Constants.SLASH).toString(); + } + + private String nodePath(String store, String product) { + + StringBuilder sb = new StringBuilder(); + // node path + String nodePath = nodePath(store); + sb.append(nodePath); + + // product path + sb.append(product).append(Constants.SLASH); + return sb.toString(); + + } + + private String nodePath(String store, String product, ImageContentFile contentImage) { + + StringBuilder sb = new StringBuilder(); + // node path + String nodePath = nodePath(store, product); + sb.append(nodePath); + + // small large + if (contentImage.getFileContentType().name().equals(FileContentType.PRODUCT.name())) { + sb.append(SMALL); + } else if (contentImage.getFileContentType().name().equals(FileContentType.PRODUCTLG.name())) { + sb.append(LARGE); + } + + return sb.append(Constants.SLASH).toString(); + + + } + + public static String getName(String filename) { + if (filename == null) { + return null; + } + int index = indexOfLastSeparator(filename); + return filename.substring(index + 1); + } + + public static int indexOfLastSeparator(String filename) { + if (filename == null) { + return -1; + } + int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR); + int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR); + return Math.max(lastUnixPos, lastWindowsPos); + } + + + + public CMSManager getCmsManager() { + return cmsManager; + } + + public void setCmsManager(CMSManager cmsManager) { + this.cmsManager = cmsManager; + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/gcp/GCPProductContentFileManager.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/gcp/GCPProductContentFileManager.java new file mode 100755 index 0000000000..9aa4436639 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/gcp/GCPProductContentFileManager.java @@ -0,0 +1,322 @@ +package com.salesmanager.core.business.modules.cms.product.gcp; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.channels.Channels; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.google.api.gax.paging.Page; +import com.google.cloud.ReadChannel; +import com.google.cloud.storage.Acl; +import com.google.cloud.storage.Acl.Role; +import com.google.cloud.storage.Acl.User; +import com.google.cloud.storage.Blob; +import com.google.cloud.storage.BlobId; +import com.google.cloud.storage.BlobInfo; +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.BucketInfo; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.Storage.BlobListOption; +import com.google.cloud.storage.Storage.BucketField; +import com.google.cloud.storage.Storage.BucketGetOption; +import com.google.cloud.storage.StorageOptions; +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.cms.impl.CMSManager; +import com.salesmanager.core.business.modules.cms.product.ProductAssetsManager; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.file.ProductImageSize; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.ImageContentFile; +import com.salesmanager.core.model.content.OutputContentFile; + +@Component("gcpProductAssetsManager") +public class GCPProductContentFileManager implements ProductAssetsManager { + + @Autowired + private CMSManager gcpAssetsManager; + + private static String DEFAULT_BUCKET_NAME = "shopizer"; + + private static final Logger LOGGER = LoggerFactory.getLogger(GCPProductContentFileManager.class); + + + + private final static String SMALL = "SMALL"; + private final static String LARGE = "LARGE"; + + /** + * + */ + private static final long serialVersionUID = 1L; + + + @Override + public OutputContentFile getProductImage(String merchantStoreCode, String productCode, + String imageName) throws ServiceException { + // TODO Auto-generated method stub + + + + return null; + } + + @Override + public OutputContentFile getProductImage(String merchantStoreCode, String productCode, + String imageName, ProductImageSize size) throws ServiceException { + InputStream inputStream = null; + try { + Storage storage = StorageOptions.getDefaultInstance().getService(); + + String bucketName = bucketName(); + + if(!this.bucketExists(storage, bucketName)) { + return null; + } + + Blob blob = storage.get(BlobId.of(bucketName, filePath(merchantStoreCode,productCode, size.name(), imageName))); + + ReadChannel reader = blob.reader(); + + inputStream = Channels.newInputStream(reader); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + IOUtils.copy(inputStream, outputStream); + OutputContentFile ct = new OutputContentFile(); + ct.setFile(outputStream); + ct.setFileName(blob.getName()); + + + + return ct; + } catch (final Exception e) { + LOGGER.error("Error while getting files", e); + throw new ServiceException(e); + + } finally { + if(inputStream!=null) { + try { + inputStream.close(); + } catch(Exception ignore) {} + } + + } + + } + + @Override + public OutputContentFile getProductImage(ProductImage productImage) throws ServiceException { + + return null; + + } + + @Override + public List getImages(Product product) throws ServiceException { + // TODO Auto-generated method stub + return null; + } + + /** + * List files + */ + @Override + public List getImages(String merchantStoreCode, + FileContentType imageContentType) throws ServiceException { + + InputStream inputStream = null; + try { + Storage storage = StorageOptions.getDefaultInstance().getService(); + + String bucketName = bucketName(); + + if(!this.bucketExists(storage, bucketName)) { + return null; + } + + Page blobs = + storage.list( + bucketName, BlobListOption.currentDirectory(), BlobListOption.prefix(merchantStoreCode)); + + List files = new ArrayList(); + for (Blob blob : blobs.iterateAll()) { + blob.getName(); + ReadChannel reader = blob.reader(); + inputStream = Channels.newInputStream(reader); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + IOUtils.copy(inputStream, outputStream); + OutputContentFile ct = new OutputContentFile(); + ct.setFile(outputStream); + files.add(ct); + } + + return files; + } catch (final Exception e) { + LOGGER.error("Error while getting files", e); + throw new ServiceException(e); + + } finally { + if(inputStream!=null) { + try { + inputStream.close(); + } catch(Exception ignore) {} + } + + } + } + + @Override + public void addProductImage(ProductImage productImage, ImageContentFile contentImage) + throws ServiceException { + + Storage storage = StorageOptions.getDefaultInstance().getService(); + + String bucketName = bucketName(); + + if(!this.bucketExists(storage, bucketName)) { + createBucket(storage, bucketName); + } + + //build filename + StringBuilder fileName = new StringBuilder() + .append(filePath(productImage.getProduct().getMerchantStore().getCode(), productImage.getProduct().getSku(), contentImage.getFileContentType())) + .append(productImage.getProductImage()); + + + try { + byte[] targetArray = IOUtils.toByteArray(contentImage.getFile()); + BlobId blobId = BlobId.of(bucketName, fileName.toString()); + BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("image/jpeg").build(); + storage.create(blobInfo, targetArray); + Acl acl = storage.createAcl(blobId, Acl.of(User.ofAllUsers(), Role.READER)); + } catch (IOException ioe) { + throw new ServiceException(ioe); + } + + + } + + @Override + public void removeProductImage(ProductImage productImage) throws ServiceException { + + //delete all image sizes + Storage storage = StorageOptions.getDefaultInstance().getService(); + + List sizes = Arrays.asList(SMALL, LARGE); + for(String size : sizes) { + String filePath = filePath(productImage.getProduct().getMerchantStore().getCode(), productImage.getProduct().getSku(), size, productImage.getProductImage()); + BlobId blobId = BlobId.of(bucketName(), filePath); + if(blobId==null) { + LOGGER.info("Image path " + filePath + " does not exist"); + return; + //throw new ServiceException("Image not found " + productImage.getProductImage()); + } + boolean deleted = storage.delete(blobId); + if (!deleted) { + LOGGER.error("Cannot delete image [" + productImage.getProductImage() + "]"); + } + } + + } + + @Override + public void removeProductImages(Product product) throws ServiceException { + + + Storage storage = StorageOptions.getDefaultInstance().getService(); + + String bucketName = bucketName(); + + Page blobs = + storage.list( + bucketName, BlobListOption.currentDirectory(), BlobListOption.prefix(product.getSku())); + + + for (Blob blob : blobs.iterateAll()) { + // do something with the blob + storage.delete(blob.getBlobId()); + } + + + } + + @Override + public void removeImages(String merchantStoreCode) throws ServiceException { + Storage storage = StorageOptions.getDefaultInstance().getService(); + + String bucketName = bucketName(); + + Page blobs = + storage.list( + bucketName, BlobListOption.currentDirectory(), BlobListOption.prefix(merchantStoreCode)); + + + for (Blob blob : blobs.iterateAll()) { + // do something with the blob + storage.delete(blob.getBlobId()); + } + + } + + private String bucketName() { + String bucketName = gcpAssetsManager.getRootName(); + if (StringUtils.isBlank(bucketName)) { + bucketName = DEFAULT_BUCKET_NAME; + } + return bucketName; + } + + private boolean bucketExists(Storage storage, String bucketName) { + Bucket bucket = storage.get(bucketName, BucketGetOption.fields(BucketField.NAME)); + if (bucket == null || !bucket.exists()) { + return false; + } + return true; + } + + private Bucket createBucket(Storage storage, String bucketName) { + return storage.create(BucketInfo.of(bucketName)); + } + + private String filePath(String merchant, String sku, FileContentType contentImage) { + StringBuilder sb = new StringBuilder(); + sb.append("products").append(Constants.SLASH); + sb.append(merchant) + .append(Constants.SLASH).append(sku).append(Constants.SLASH); + + // small large + if (contentImage.name().equals(FileContentType.PRODUCT.name())) { + sb.append(SMALL); + } else if (contentImage.name().equals(FileContentType.PRODUCTLG.name())) { + sb.append(LARGE); + } + + return sb.append(Constants.SLASH).toString(); + + } + + private String filePath(String merchant, String sku, String size, String fileName) { + StringBuilder sb = new StringBuilder(); + sb.append("products").append(Constants.SLASH); + sb.append(merchant) + .append(Constants.SLASH).append(sku).append(Constants.SLASH); + + sb.append(size); + sb.append(Constants.SLASH).append(fileName); + + return sb.toString(); + + } + + +} \ No newline at end of file diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/infinispan/CmsImageFileManagerImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/infinispan/CmsImageFileManagerImpl.java new file mode 100755 index 0000000000..6d7ede8d70 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/infinispan/CmsImageFileManagerImpl.java @@ -0,0 +1,476 @@ +package com.salesmanager.core.business.modules.cms.product.infinispan; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.net.FileNameMap; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import javax.annotation.PostConstruct; +import org.apache.commons.io.IOUtils; +import org.infinispan.tree.Fqn; +import org.infinispan.tree.Node; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.cms.impl.CMSManager; +import com.salesmanager.core.business.modules.cms.impl.CacheManager; +import com.salesmanager.core.business.modules.cms.product.ProductAssetsManager; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.file.ProductImageSize; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.ImageContentFile; +import com.salesmanager.core.model.content.OutputContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; + +/** + * Manager for storing in retrieving image files from the CMS This is a layer on top of Infinispan + * https://docs.jboss.org/author/display/ISPN/Tree+API+Module + * + * Manages - Product images + * + * @author Carl Samson + */ +public class CmsImageFileManagerImpl implements ProductAssetsManager { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private static final Logger LOGGER = LoggerFactory.getLogger(CmsImageFileManagerImpl.class); + + private static CmsImageFileManagerImpl fileManager = null; + + private final static String ROOT_NAME = "product-merchant"; + + private final static String SMALL = "SMALL"; + private final static String LARGE = "LARGE"; + + private String rootName = ROOT_NAME; + + private CacheManager cacheManager; + + + /** + * Requires to stop the engine when image servlet un-deploys + */ + public void stopFileManager() { + + try { + LOGGER.info("Stopping CMS"); + cacheManager.getManager().stop(); + } catch (Exception e) { + LOGGER.error("Error while stopping CmsImageFileManager", e); + } + } + + @PostConstruct + void init() { + + this.rootName = cacheManager.getRootName(); + LOGGER.info("init " + getClass().getName() + " setting root" + this.rootName); + + } + + public static CmsImageFileManagerImpl getInstance() { + + if (fileManager == null) { + fileManager = new CmsImageFileManagerImpl(); + } + + + return fileManager; + + } + + private CmsImageFileManagerImpl() { + + } + + /** + * root -productFiles -merchant-id PRODUCT-ID(key) -> CacheAttribute(value) - image 1 - image 2 - + * image 3 + */ + + @Override + public void addProductImage(ProductImage productImage, ImageContentFile contentImage) + throws ServiceException { + + if (cacheManager.getTreeCache() == null) { + throw new ServiceException( + "CmsImageFileManagerInfinispan has a null cacheManager.getTreeCache()"); + } + + try { + + // node + StringBuilder nodePath = new StringBuilder(); + nodePath.append(productImage.getProduct().getMerchantStore().getCode()) + .append(Constants.SLASH).append(productImage.getProduct().getSku()) + .append(Constants.SLASH); + + + if (contentImage.getFileContentType().name().equals(FileContentType.PRODUCT.name())) { + nodePath.append(SMALL); + } else if (contentImage.getFileContentType().name() + .equals(FileContentType.PRODUCTLG.name())) { + nodePath.append(LARGE); + } + + Node productNode = this.getNode(nodePath.toString()); + + + InputStream isFile = contentImage.getFile(); + + ByteArrayOutputStream output = new ByteArrayOutputStream(); + IOUtils.copy(isFile, output); + + + // object for a given product containing all images + productNode.put(contentImage.getFileName(), output.toByteArray()); + + + + } catch (Exception e) { + + throw new ServiceException(e); + + } + + } + + @Override + public OutputContentFile getProductImage(ProductImage productImage) throws ServiceException { + + return getProductImage(productImage.getProduct().getMerchantStore().getCode(), + productImage.getProduct().getSku(), productImage.getProductImage()); + + } + + + public List getImages(MerchantStore store, FileContentType imageContentType) + throws ServiceException { + + return getImages(store.getCode(), imageContentType); + + } + + @Override + public List getImages(Product product) throws ServiceException { + + if (cacheManager.getTreeCache() == null) { + throw new ServiceException( + "CmsImageFileManagerInfinispan has a null cacheManager.getTreeCache()"); + } + + List images = new ArrayList(); + + + try { + + + FileNameMap fileNameMap = URLConnection.getFileNameMap(); + StringBuilder nodePath = new StringBuilder(); + nodePath.append(product.getMerchantStore().getCode()); + + Node merchantNode = this.getNode(nodePath.toString()); + + if (merchantNode == null) { + return null; + } + + + for (String key : merchantNode.getKeys()) { + + byte[] imageBytes = (byte[]) merchantNode.get(key); + + OutputContentFile contentImage = new OutputContentFile(); + + InputStream input = new ByteArrayInputStream(imageBytes); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + IOUtils.copy(input, output); + + String contentType = fileNameMap.getContentTypeFor(key); + + contentImage.setFile(output); + contentImage.setMimeType(contentType); + contentImage.setFileName(key); + + images.add(contentImage); + + + } + + + } + + catch (Exception e) { + throw new ServiceException(e); + } finally { + + } + + return images; + } + + + + @SuppressWarnings("unchecked") + @Override + public void removeImages(final String merchantStoreCode) throws ServiceException { + if (cacheManager.getTreeCache() == null) { + throw new ServiceException( + "CmsImageFileManagerInfinispan has a null cacheManager.getTreeCache()"); + } + + try { + + + final StringBuilder merchantPath = new StringBuilder(); + merchantPath.append(getRootName()).append(merchantStoreCode); + cacheManager.getTreeCache().getRoot().remove(merchantPath.toString()); + + + + } catch (Exception e) { + throw new ServiceException(e); + } finally { + + } + + } + + + @Override + public void removeProductImage(ProductImage productImage) throws ServiceException { + + if (cacheManager.getTreeCache() == null) { + throw new ServiceException( + "CmsImageFileManagerInfinispan has a null cacheManager.getTreeCache()"); + } + + try { + + + StringBuilder nodePath = new StringBuilder(); + nodePath.append(productImage.getProduct().getMerchantStore().getCode()) + .append(Constants.SLASH).append(productImage.getProduct().getSku()); + + + Node productNode = this.getNode(nodePath.toString()); + productNode.remove(productImage.getProductImage()); + + + + } catch (Exception e) { + throw new ServiceException(e); + } finally { + + } + + } + + @Override + public void removeProductImages(Product product) throws ServiceException { + + if (cacheManager.getTreeCache() == null) { + throw new ServiceException( + "CmsImageFileManagerInfinispan has a null cacheManager.getTreeCache()"); + } + + try { + + + StringBuilder nodePath = new StringBuilder(); + nodePath.append(product.getMerchantStore().getCode()); + + + Node merchantNode = this.getNode(nodePath.toString()); + + merchantNode.remove(product.getSku()); + + + + } catch (Exception e) { + throw new ServiceException(e); + } finally { + + } + + } + + + @Override + public List getImages(final String merchantStoreCode, + FileContentType imageContentType) throws ServiceException { + if (cacheManager.getTreeCache() == null) { + throw new ServiceException( + "CmsImageFileManagerInfinispan has a null cacheManager.getTreeCache()"); + } + List images = new ArrayList(); + FileNameMap fileNameMap = URLConnection.getFileNameMap(); + + try { + + + StringBuilder nodePath = new StringBuilder(); + nodePath.append(merchantStoreCode); + + + Node merchantNode = this.getNode(nodePath.toString()); + + Set> childs = merchantNode.getChildren(); + + // TODO image sizes + for (Node node : childs) { + + for (String key : node.getKeys()) { + + + byte[] imageBytes = (byte[]) merchantNode.get(key); + + OutputContentFile contentImage = new OutputContentFile(); + + InputStream input = new ByteArrayInputStream(imageBytes); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + IOUtils.copy(input, output); + + String contentType = fileNameMap.getContentTypeFor(key); + + contentImage.setFile(output); + contentImage.setMimeType(contentType); + contentImage.setFileName(key); + + images.add(contentImage); + + + } + + } + + + + } catch (Exception e) { + throw new ServiceException(e); + } finally { + + } + + return images; + } + + @Override + public OutputContentFile getProductImage(String merchantStoreCode, String productCode, + String imageName) throws ServiceException { + return getProductImage(merchantStoreCode, productCode, imageName, + ProductImageSize.SMALL.name()); + } + + @Override + public OutputContentFile getProductImage(String merchantStoreCode, String productCode, + String imageName, ProductImageSize size) throws ServiceException { + return getProductImage(merchantStoreCode, productCode, imageName, size.name()); + } + + private OutputContentFile getProductImage(String merchantStoreCode, String productCode, + String imageName, String size) throws ServiceException { + + if (cacheManager.getTreeCache() == null) { + throw new ServiceException( + "CmsImageFileManagerInfinispan has a null cacheManager.getTreeCache()"); + } + InputStream input = null; + OutputContentFile contentImage = new OutputContentFile(); + try { + + FileNameMap fileNameMap = URLConnection.getFileNameMap(); + + // SMALL by default + StringBuilder nodePath = new StringBuilder(); + nodePath.append(merchantStoreCode).append(Constants.SLASH).append(productCode) + .append(Constants.SLASH).append(size); + + Node productNode = this.getNode(nodePath.toString()); + + + byte[] imageBytes = (byte[]) productNode.get(imageName); + + if (imageBytes == null) { + LOGGER.warn("Image " + imageName + " does not exist"); + return null;// no post processing will occur + } + + input = new ByteArrayInputStream(imageBytes); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + IOUtils.copy(input, output); + + String contentType = fileNameMap.getContentTypeFor(imageName); + + contentImage.setFile(output); + contentImage.setMimeType(contentType); + contentImage.setFileName(imageName); + + + + } catch (Exception e) { + throw new ServiceException(e); + } finally { + if (input != null) { + try { + input.close(); + } catch (Exception ignore) { + } + } + } + + return contentImage; + + } + + + @SuppressWarnings("unchecked") + private Node getNode(final String node) { + LOGGER.debug("Fetching node for store {} from Infinispan", node); + final StringBuilder merchantPath = new StringBuilder(); + merchantPath.append(getRootName()).append(node); + + Fqn contentFilesFqn = Fqn.fromString(merchantPath.toString()); + + Node nd = cacheManager.getTreeCache().getRoot().getChild(contentFilesFqn); + + if (nd == null) { + + cacheManager.getTreeCache().getRoot().addChild(contentFilesFqn); + nd = cacheManager.getTreeCache().getRoot().getChild(contentFilesFqn); + + } + + return nd; + + } + + public CacheManager getCacheManager() { + return cacheManager; + } + + public void setCacheManager(CacheManager cacheManager) { + this.cacheManager = cacheManager; + } + + public void setRootName(String rootName) { + this.rootName = rootName; + } + + public String getRootName() { + return rootName; + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/local/CmsImageFileManagerImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/local/CmsImageFileManagerImpl.java new file mode 100755 index 0000000000..7432cb6dd2 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/cms/product/local/CmsImageFileManagerImpl.java @@ -0,0 +1,309 @@ +package com.salesmanager.core.business.modules.cms.product.local; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.List; +import javax.annotation.PostConstruct; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.cms.impl.CMSManager; +import com.salesmanager.core.business.modules.cms.impl.LocalCacheManagerImpl; +import com.salesmanager.core.business.modules.cms.product.ProductAssetsManager; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.file.ProductImageSize; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.ImageContentFile; +import com.salesmanager.core.model.content.OutputContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; + +/** + * Manager for storing and deleting image files from the CMS which is a web server + * + * Manages - Product images + * + * @author Carl Samson + */ +public class CmsImageFileManagerImpl + implements ProductAssetsManager { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private static final Logger LOGGER = LoggerFactory.getLogger(CmsImageFileManagerImpl.class); + + private static CmsImageFileManagerImpl fileManager = null; + + private final static String ROOT_NAME = ""; + + private final static String SMALL = "SMALL"; + private final static String LARGE = "LARGE"; + + private static final String ROOT_CONTAINER = "products"; + + private String rootName = ROOT_NAME; + + private LocalCacheManagerImpl cacheManager; + + @PostConstruct + void init() { + + this.rootName = ((CMSManager) cacheManager).getRootName(); + LOGGER.info("init " + getClass().getName() + " setting root" + this.rootName); + + } + + public static CmsImageFileManagerImpl getInstance() { + + if (fileManager == null) { + fileManager = new CmsImageFileManagerImpl(); + } + + return fileManager; + + } + + private CmsImageFileManagerImpl() { + + } + + /** + * root/products///1.jpg + */ + + @Override + public void addProductImage(ProductImage productImage, ImageContentFile contentImage) + throws ServiceException { + + + try { + + // base path + String rootPath = this.buildRootPath(); + Path confDir = Paths.get(rootPath); + this.createDirectoryIfNorExist(confDir); + + // node path + StringBuilder nodePath = new StringBuilder(); + nodePath.append(rootPath).append(productImage.getProduct().getMerchantStore().getCode()); + Path merchantPath = Paths.get(nodePath.toString()); + this.createDirectoryIfNorExist(merchantPath); + + // product path + nodePath.append(Constants.SLASH).append(productImage.getProduct().getSku()) + .append(Constants.SLASH); + Path dirPath = Paths.get(nodePath.toString()); + this.createDirectoryIfNorExist(dirPath); + + // small large + if (contentImage.getFileContentType().name().equals(FileContentType.PRODUCT.name())) { + nodePath.append(SMALL); + } else if (contentImage.getFileContentType().name() + .equals(FileContentType.PRODUCTLG.name())) { + nodePath.append(LARGE); + } + Path sizePath = Paths.get(nodePath.toString()); + this.createDirectoryIfNorExist(sizePath); + + + // file creation + nodePath.append(Constants.SLASH).append(contentImage.getFileName()); + + + Path path = Paths.get(nodePath.toString()); + InputStream isFile = contentImage.getFile(); + + Files.copy(isFile, path, StandardCopyOption.REPLACE_EXISTING); + + + } catch (Exception e) { + + throw new ServiceException(e); + + } + + } + + @Override + public OutputContentFile getProductImage(ProductImage productImage) throws ServiceException { + + // the web server takes care of the images + return null; + + } + + + public List getImages(MerchantStore store, FileContentType imageContentType) + throws ServiceException { + + // the web server takes care of the images + + return null; + + } + + @Override + public List getImages(Product product) throws ServiceException { + + // the web server takes care of the images + + return null; + } + + + + @Override + public void removeImages(final String merchantStoreCode) throws ServiceException { + + try { + + + StringBuilder merchantPath = new StringBuilder(); + merchantPath.append(buildRootPath()).append(Constants.SLASH).append(merchantStoreCode); + + Path path = Paths.get(merchantPath.toString()); + + Files.deleteIfExists(path); + + + } catch (Exception e) { + throw new ServiceException(e); + } + + + } + + + @Override + public void removeProductImage(ProductImage productImage) throws ServiceException { + + + try { + + + StringBuilder nodePath = new StringBuilder(); + nodePath.append(buildRootPath()).append(Constants.SLASH) + .append(productImage.getProduct().getMerchantStore().getCode()).append(Constants.SLASH) + .append(productImage.getProduct().getSku()); + + // delete small + StringBuilder smallPath = new StringBuilder(nodePath); + smallPath.append(Constants.SLASH).append(SMALL).append(Constants.SLASH) + .append(productImage.getProductImage()); + + + Path path = Paths.get(smallPath.toString()); + + Files.deleteIfExists(path); + + // delete large + StringBuilder largePath = new StringBuilder(nodePath); + largePath.append(Constants.SLASH).append(LARGE).append(Constants.SLASH) + .append(productImage.getProductImage()); + + + path = Paths.get(largePath.toString()); + + Files.deleteIfExists(path); + + } catch (Exception e) { + throw new ServiceException(e); + } + + + } + + @Override + public void removeProductImages(Product product) throws ServiceException { + + try { + + + StringBuilder nodePath = new StringBuilder(); + nodePath.append(buildRootPath()).append(Constants.SLASH) + .append(product.getMerchantStore().getCode()).append(Constants.SLASH) + .append(product.getSku()); + + + Path path = Paths.get(nodePath.toString()); + + Files.deleteIfExists(path); + + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + + @Override + public List getImages(final String merchantStoreCode, + FileContentType imageContentType) throws ServiceException { + + // the web server taks care of the images + + return null; + } + + @Override + public OutputContentFile getProductImage(String merchantStoreCode, String productCode, + String imageName) throws ServiceException { + return getProductImage(merchantStoreCode, productCode, imageName, + ProductImageSize.SMALL.name()); + } + + @Override + public OutputContentFile getProductImage(String merchantStoreCode, String productCode, + String imageName, ProductImageSize size) throws ServiceException { + return getProductImage(merchantStoreCode, productCode, imageName, size.name()); + } + + private OutputContentFile getProductImage(String merchantStoreCode, String productCode, + String imageName, String size) throws ServiceException { + + return null; + + } + + + private String buildRootPath() { + return new StringBuilder().append(getRootName()).append(Constants.SLASH).append(ROOT_CONTAINER) + .append(Constants.SLASH).toString(); + + } + + + private void createDirectoryIfNorExist(Path path) throws IOException { + + if (Files.notExists(path)) { + Files.createDirectory(path); + } + } + + public void setRootName(String rootName) { + this.rootName = rootName; + } + + public String getRootName() { + return rootName; + } + + public LocalCacheManagerImpl getCacheManager() { + return cacheManager; + } + + public void setCacheManager(LocalCacheManagerImpl cacheManager) { + this.cacheManager = cacheManager; + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/email/DefaultEmailSenderImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/email/DefaultEmailSenderImpl.java new file mode 100755 index 0000000000..394d3b2d8e --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/email/DefaultEmailSenderImpl.java @@ -0,0 +1,188 @@ +package com.salesmanager.core.business.modules.email; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.StringWriter; +import java.util.Map; +import java.util.Properties; +import javax.inject.Inject; +import javax.mail.BodyPart; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Multipart; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; +import org.springframework.mail.MailPreparationException; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; +import org.springframework.mail.javamail.MimeMessagePreparator; +import org.springframework.stereotype.Component; +import freemarker.template.Configuration; +import freemarker.template.Template; +import freemarker.template.TemplateException; + +@Component("defaultEmailSender") +public class DefaultEmailSenderImpl implements EmailModule { + + @Inject + private Configuration freemarkerMailConfiguration; + + @Inject + private JavaMailSender mailSender; + + private static final String CHARSET = "UTF-8"; + private EmailConfig emailConfig; + + private final static String TEMPLATE_PATH = "templates/email"; + + @Override + public void send(Email email) throws Exception { + + final String eml = email.getFrom(); + final String from = email.getFromEmail(); + final String to = email.getTo(); + final String subject = email.getSubject(); + final String tmpl = email.getTemplateName(); + final Map templateTokens = email.getTemplateTokens(); + + MimeMessagePreparator preparator = new MimeMessagePreparator() { + public void prepare(MimeMessage mimeMessage) throws MessagingException, IOException { + + JavaMailSenderImpl impl = (JavaMailSenderImpl) mailSender; + // if email configuration is present in Database, use the same + if (emailConfig != null) { + impl.setProtocol(emailConfig.getProtocol()); + impl.setHost(emailConfig.getHost()); + impl.setPort(Integer.parseInt(emailConfig.getPort())); + impl.setUsername(emailConfig.getUsername()); + impl.setPassword(emailConfig.getPassword()); + + Properties prop = new Properties(); + prop.put("mail.smtp.auth", emailConfig.isSmtpAuth()); + prop.put("mail.smtp.starttls.enable", emailConfig.isStarttls()); + impl.setJavaMailProperties(prop); + } + + mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(to)); + + InternetAddress inetAddress = new InternetAddress(); + + inetAddress.setPersonal(eml); + inetAddress.setAddress(from); + + mimeMessage.setFrom(inetAddress); + mimeMessage.setSubject(subject); + + Multipart mp = new MimeMultipart("alternative"); + + // Create a "text" Multipart message + BodyPart textPart = new MimeBodyPart(); + freemarkerMailConfiguration.setClassForTemplateLoading(DefaultEmailSenderImpl.class, "/"); + Template textTemplate = freemarkerMailConfiguration.getTemplate( + new StringBuilder(TEMPLATE_PATH).append("/").append(tmpl).toString()); + final StringWriter textWriter = new StringWriter(); + try { + textTemplate.process(templateTokens, textWriter); + } catch (TemplateException e) { + throw new MailPreparationException("Can't generate text mail", e); + } + textPart.setDataHandler(new javax.activation.DataHandler(new javax.activation.DataSource() { + public InputStream getInputStream() throws IOException { + // return new StringBufferInputStream(textWriter + // .toString()); + return new ByteArrayInputStream(textWriter.toString().getBytes(CHARSET)); + } + + public OutputStream getOutputStream() throws IOException { + throw new IOException("Read-only data"); + } + + public String getContentType() { + return "text/plain"; + } + + public String getName() { + return "main"; + } + })); + mp.addBodyPart(textPart); + + // Create a "HTML" Multipart message + Multipart htmlContent = new MimeMultipart("related"); + BodyPart htmlPage = new MimeBodyPart(); + freemarkerMailConfiguration.setClassForTemplateLoading(DefaultEmailSenderImpl.class, "/"); + Template htmlTemplate = freemarkerMailConfiguration.getTemplate( + new StringBuilder(TEMPLATE_PATH).append("/").append(tmpl).toString()); + final StringWriter htmlWriter = new StringWriter(); + try { + htmlTemplate.process(templateTokens, htmlWriter); + } catch (TemplateException e) { + throw new MailPreparationException("Can't generate HTML mail", e); + } + htmlPage.setDataHandler(new javax.activation.DataHandler(new javax.activation.DataSource() { + public InputStream getInputStream() throws IOException { + // return new StringBufferInputStream(htmlWriter + // .toString()); + return new ByteArrayInputStream(textWriter.toString().getBytes(CHARSET)); + } + + public OutputStream getOutputStream() throws IOException { + throw new IOException("Read-only data"); + } + + public String getContentType() { + return "text/html"; + } + + public String getName() { + return "main"; + } + })); + htmlContent.addBodyPart(htmlPage); + BodyPart htmlPart = new MimeBodyPart(); + htmlPart.setContent(htmlContent); + mp.addBodyPart(htmlPart); + + mimeMessage.setContent(mp); + + // if(attachment!=null) { + // MimeMessageHelper messageHelper = new + // MimeMessageHelper(mimeMessage, true); + // messageHelper.addAttachment(attachmentFileName, attachment); + // } + + } + }; + + mailSender.send(preparator); + } + + public Configuration getFreemarkerMailConfiguration() { + return freemarkerMailConfiguration; + } + + public void setFreemarkerMailConfiguration(Configuration freemarkerMailConfiguration) { + this.freemarkerMailConfiguration = freemarkerMailConfiguration; + } + + public JavaMailSender getMailSender() { + return mailSender; + } + + public void setMailSender(JavaMailSender mailSender) { + this.mailSender = mailSender; + } + + public EmailConfig getEmailConfig() { + return emailConfig; + } + + public void setEmailConfig(EmailConfig emailConfig) { + this.emailConfig = emailConfig; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/email/Email.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/email/Email.java new file mode 100755 index 0000000000..f51aacd409 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/email/Email.java @@ -0,0 +1,70 @@ +package com.salesmanager.core.business.modules.email; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +public class Email implements Serializable { + + + /** + * + */ + private static final long serialVersionUID = 6481794982612826257L; + private String from; + private String fromEmail; + private String to; + private String subject; + private String templateName; + + private Map templateTokens = new HashMap(); + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public String getTemplateName() { + return templateName; + } + + public void setTemplateName(String templateName) { + this.templateName = templateName; + } + + public Map getTemplateTokens() { + return templateTokens; + } + + public void setTemplateTokens(Map templateTokens) { + this.templateTokens = templateTokens; + } + + public void setFromEmail(String fromEmail) { + this.fromEmail = fromEmail; + } + + public String getFromEmail() { + return fromEmail; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/email/EmailComponent.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/email/EmailComponent.java new file mode 100755 index 0000000000..bfe17ec9a4 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/email/EmailComponent.java @@ -0,0 +1,53 @@ +package com.salesmanager.core.business.modules.email; + +import javax.inject.Inject; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component("htmlEmailSender") +public class EmailComponent implements HtmlEmailSender { + + @Value("${config.emailSender}") + private String emailSender; + + @Inject + private EmailModule defaultEmailSender; + + @Inject + private EmailModule sesEmailSender; + + @Override + public void send(Email email) throws Exception { + switch(emailSender) + { + case "default": + defaultEmailSender.send(email); + break; + case "ses": + sesEmailSender.send(email); + break; + default: + throw new Exception("No email implementation for " + emailSender); + } + + } + + @Override + public void setEmailConfig(EmailConfig emailConfig) { + switch(emailSender) + { + case "default": + defaultEmailSender.setEmailConfig(emailConfig); + break; + case "ses": + sesEmailSender.setEmailConfig(emailConfig); + break; + default: + + } + + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/email/EmailConfig.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/email/EmailConfig.java new file mode 100755 index 0000000000..ec8ee923a4 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/email/EmailConfig.java @@ -0,0 +1,113 @@ +package com.salesmanager.core.business.modules.email; + +import org.json.simple.JSONAware; +import org.json.simple.JSONObject; + +public class EmailConfig implements JSONAware { + + private String host; + private String port; + private String protocol; + private String username; + private String password; + private boolean smtpAuth = false; + private boolean starttls = false; + + private String emailTemplatesPath = null; + + @SuppressWarnings("unchecked") + @Override + public String toJSONString() { + JSONObject data = new JSONObject(); + data.put("host", this.getHost()); + data.put("port", this.getPort()); + data.put("protocol", this.getProtocol()); + data.put("username", this.getUsername()); + data.put("smtpAuth", this.isSmtpAuth()); + data.put("starttls", this.isStarttls()); + data.put("password", this.getPassword()); + return data.toJSONString(); + } + + + + public boolean isSmtpAuth() { + return smtpAuth; + } + public void setSmtpAuth(boolean smtpAuth) { + this.smtpAuth = smtpAuth; + } + public boolean isStarttls() { + return starttls; + } + public void setStarttls(boolean starttls) { + this.starttls = starttls; + } + public void setEmailTemplatesPath(String emailTemplatesPath) { + this.emailTemplatesPath = emailTemplatesPath; + } + public String getEmailTemplatesPath() { + return emailTemplatesPath; + } + + + + public String getHost() { + return host; + } + + + + public void setHost(String host) { + this.host = host; + } + + + + public String getPort() { + return port; + } + + + + public void setPort(String port) { + this.port = port; + } + + + + public String getProtocol() { + return protocol; + } + + + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + + + public String getUsername() { + return username; + } + + + + public void setUsername(String username) { + this.username = username; + } + + + + public String getPassword() { + return password; + } + + + + public void setPassword(String password) { + this.password = password; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/email/EmailModule.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/email/EmailModule.java new file mode 100755 index 0000000000..7804560422 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/email/EmailModule.java @@ -0,0 +1,9 @@ +package com.salesmanager.core.business.modules.email; + +public interface EmailModule { + + void send(final Email email) throws Exception; + + void setEmailConfig(EmailConfig emailConfig); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/email/HtmlEmailSender.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/email/HtmlEmailSender.java new file mode 100755 index 0000000000..2bbf3da9b7 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/email/HtmlEmailSender.java @@ -0,0 +1,10 @@ +package com.salesmanager.core.business.modules.email; + + +public interface HtmlEmailSender { + + void send(final Email email) throws Exception; + + void setEmailConfig(EmailConfig emailConfig); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/email/SESEmailSenderImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/email/SESEmailSenderImpl.java new file mode 100755 index 0000000000..212faf6add --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/email/SESEmailSenderImpl.java @@ -0,0 +1,99 @@ +package com.salesmanager.core.business.modules.email; + +import java.io.StringWriter; +import javax.inject.Inject; +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.mail.MailPreparationException; +import org.springframework.stereotype.Component; +import com.amazonaws.regions.Regions; +import com.amazonaws.services.simpleemail.AmazonSimpleEmailService; +import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClientBuilder; +import com.amazonaws.services.simpleemail.model.Body; +import com.amazonaws.services.simpleemail.model.Content; +import com.amazonaws.services.simpleemail.model.Destination; +import com.amazonaws.services.simpleemail.model.Message; +import com.amazonaws.services.simpleemail.model.SendEmailRequest; +import freemarker.template.Configuration; +import freemarker.template.Template; +import freemarker.template.TemplateException; + +/** + * AWS HTML email sender + * + * @author carlsamson + * + */ +@Component("sesEmailSender") +public class SESEmailSenderImpl implements EmailModule { + + @Inject + private Configuration freemarkerMailConfiguration; + + @Value("${config.emailSender.region}") + private String region; + + private final static String TEMPLATE_PATH = "templates/email"; + + // The configuration set to use for this email. If you do not want to use a + // configuration set, comment the following variable and the + // .withConfigurationSetName(CONFIGSET); argument below. + //static final String CONFIGSET = "ConfigSet"; + + + // The email body for recipients with non-HTML email clients. + static final String TEXTBODY = + "This email was sent through Amazon SES " + "using the AWS SDK for Java."; + + @Override + public void send(Email email) throws Exception { + + + + //String eml = email.getFrom(); + + Validate.notNull(region,"AWS region is null"); + + AmazonSimpleEmailService client = AmazonSimpleEmailServiceClientBuilder.standard() + // Replace US_WEST_2 with the AWS Region you're using for + // Amazon SES. + .withRegion(Regions.valueOf(region.toUpperCase())).build(); + SendEmailRequest request = new SendEmailRequest() + .withDestination(new Destination().withToAddresses(email.getTo())) + .withMessage(new Message() + .withBody(new Body().withHtml(new Content().withCharset("UTF-8").withData(prepareHtml(email))) + .withText(new Content().withCharset("UTF-8").withData(TEXTBODY))) + .withSubject(new Content().withCharset("UTF-8").withData(email.getSubject()))) + .withSource(email.getFromEmail()); + // Comment or remove the next line if you are not using a + // configuration set + //.withConfigurationSetName(CONFIGSET); + client.sendEmail(request); + + + } + + private String prepareHtml(Email email) throws Exception { + + + freemarkerMailConfiguration.setClassForTemplateLoading(DefaultEmailSenderImpl.class, "/"); + Template htmlTemplate = freemarkerMailConfiguration.getTemplate(new StringBuilder(TEMPLATE_PATH) + .append("/").append(email.getTemplateName()).toString()); + final StringWriter htmlWriter = new StringWriter(); + try { + htmlTemplate.process(email.getTemplateTokens(), htmlWriter); + } catch (TemplateException e) { + throw new MailPreparationException("Can't generate HTML mail", e); + } + + return htmlWriter.toString(); + + } + + @Override + public void setEmailConfig(EmailConfig emailConfig) { + // TODO Auto-generated method stub + + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/IntegrationException.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/IntegrationException.java new file mode 100755 index 0000000000..8374f14de0 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/IntegrationException.java @@ -0,0 +1,62 @@ +package com.salesmanager.core.business.modules.integration; + +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; + + +public class IntegrationException extends ServiceException { + + + /** + * + */ + private static final long serialVersionUID = 1L; + + public static final int ERROR_VALIDATION_SAVE = 100; + public static final int TRANSACTION_EXCEPTION = 99; + + private List errorFields; + + private int errorCode = 0; + + public int getErrorCode() { + return errorCode; + } + + public void setErrorCode(int errorCode) { + this.errorCode = errorCode; + } + + public IntegrationException(Exception e) { + super(e); + } + + public IntegrationException(String message, Exception e) { + super(message,e); + } + + public IntegrationException(int code, String message) { + + super(message); + this.errorCode = code; + } + + public IntegrationException(int code) { + + this.errorCode = code; + } + + public IntegrationException(String message) { + super(message); + } + + public void setErrorFields(List errorFields) { + this.errorFields = errorFields; + } + + public List getErrorFields() { + return errorFields; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/BeanStreamPayment.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/BeanStreamPayment.java new file mode 100755 index 0000000000..49040e9c66 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/BeanStreamPayment.java @@ -0,0 +1,738 @@ +package com.salesmanager.core.business.modules.integration.payment.impl; + +import java.io.BufferedReader; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.InputStreamReader; +import java.math.BigDecimal; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.UUID; + +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.salesmanager.core.business.services.system.MerchantLogService; +import com.salesmanager.core.business.utils.CreditCardUtils; +import com.salesmanager.core.business.utils.ProductPriceUtils; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.payments.CreditCardPayment; +import com.salesmanager.core.model.payments.Payment; +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.payments.TransactionType; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.model.system.MerchantLog; +import com.salesmanager.core.model.system.ModuleConfig; +import com.salesmanager.core.modules.integration.IntegrationException; +import com.salesmanager.core.modules.integration.payment.model.PaymentModule; + + +public class BeanStreamPayment implements PaymentModule { + + @Inject + private ProductPriceUtils productPriceUtils; + + @Inject + private MerchantLogService merchantLogService; + + + + private static final Logger LOGGER = LoggerFactory.getLogger(BeanStreamPayment.class); + + @Override + public Transaction initTransaction(MerchantStore store, Customer customer, + BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + // TODO Auto-generated method stub + return null; + } + + @Override + public Transaction authorize(MerchantStore store, Customer customer, + List items, BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + return processTransaction(store, customer, TransactionType.AUTHORIZE, + amount, + payment, + configuration, + module); + } + + @Override + public Transaction capture(MerchantStore store, Customer customer, + Order order, Transaction capturableTransaction, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + + try { + + + + //authorize a preauth + + + String trnID = capturableTransaction.getTransactionDetails().get("TRANSACTIONID"); + + String amnt = productPriceUtils.getAdminFormatedAmount(store, order.getTotal()); + + /** + merchant_id=123456789&requestType=BACKEND + &trnType=PAC&username=user1234&password=pass1234&trnID=1000 + 2115 --> requires also adjId [not documented] + **/ + + StringBuilder messageString = new StringBuilder(); + messageString.append("requestType=BACKEND&"); + messageString.append("merchant_id=").append(configuration.getIntegrationKeys().get("merchantid")).append("&"); + messageString.append("trnType=").append("PAC").append("&"); + messageString.append("username=").append(configuration.getIntegrationKeys().get("username")).append("&"); + messageString.append("password=").append(configuration.getIntegrationKeys().get("password")).append("&"); + messageString.append("trnAmount=").append(amnt).append("&"); + messageString.append("adjId=").append(trnID).append("&"); + messageString.append("trnID=").append(trnID); + + LOGGER.debug("REQUEST SENT TO BEANSTREAM -> " + messageString.toString()); + + + + return sendTransaction(null, store, messageString.toString(), "PAC", TransactionType.CAPTURE, PaymentType.CREDITCARD, order.getTotal(), configuration, module); + + } catch(Exception e) { + + if(e instanceof IntegrationException) + throw (IntegrationException)e; + throw new IntegrationException("Error while processing BeanStream transaction",e); + + } + + } + + @Override + public Transaction authorizeAndCapture(MerchantStore store, Customer customer, + List items, BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + return processTransaction( + store, + customer, + TransactionType.AUTHORIZECAPTURE, + amount, + payment, + configuration, + module); + } + + @Override + public Transaction refund(boolean partial, MerchantStore store, Transaction transaction, + Order order, BigDecimal amount, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + + + + HttpURLConnection conn = null; + + try { + + + boolean bSandbox = false; + if (configuration.getEnvironment().equals("TEST")) {// sandbox + bSandbox = true; + } + + ModuleConfig configs = module.getModuleConfigs().get("PROD"); + + if (bSandbox) { + configs = module.getModuleConfigs().get("TEST"); + } + + if(configs==null) { + throw new IntegrationException("Module not configured for TEST or PROD"); + } + + + String server = new StringBuffer().append( + + configs.getScheme()).append("://") + .append(configs.getHost()) + .append(":") + .append(configs.getPort()) + .append(configs.getUri()).toString(); + + String trnID = transaction.getTransactionDetails().get("TRANSACTIONID"); + + String amnt = productPriceUtils.getAdminFormatedAmount(store, amount); + + /** + merchant_id=123456789&requestType=BACKEND + &trnType=R&username=user1234&password=pass1234 + &trnOrderNumber=1234&trnAmount=1.00&adjId=1000 + 2115 + **/ + StringBuilder messageString = new StringBuilder(); + + + + messageString.append("requestType=BACKEND&"); + messageString.append("merchant_id=").append(configuration.getIntegrationKeys().get("merchantid")).append("&"); + messageString.append("trnType=").append("R").append("&"); + messageString.append("username=").append(configuration.getIntegrationKeys().get("username")).append("&"); + messageString.append("password=").append(configuration.getIntegrationKeys().get("password")).append("&"); + messageString.append("trnOrderNumber=").append(transaction.getTransactionDetails().get("TRNORDERNUMBER")).append("&"); + messageString.append("trnAmount=").append(amnt).append("&"); + messageString.append("adjId=").append(trnID); + + LOGGER.debug("REQUEST SENT TO BEANSTREAM -> " + messageString.toString()); + + + + + URL postURL = new URL(server); + conn = (HttpURLConnection) postURL.openConnection(); + + + + + return sendTransaction(null, store, messageString.toString(), "R", TransactionType.REFUND, PaymentType.CREDITCARD, amount, configuration, module); + + } catch(Exception e) { + + if(e instanceof IntegrationException) + throw (IntegrationException)e; + throw new IntegrationException("Error while processing BeanStream transaction",e); + + } finally { + + + if (conn != null) { + try { + conn.disconnect(); + } catch (Exception ignore) { + // TODO: handle exception + } + } + } + + + + } + + + private Transaction sendTransaction( + String orderNumber, + MerchantStore store, + String transaction, + String beanstreamType, + TransactionType transactionType, + PaymentType paymentType, + BigDecimal amount, + IntegrationConfiguration configuration, + IntegrationModule module + ) throws IntegrationException { + + String agent = "Mozilla/4.0"; + String respText = ""; + Map nvp = null; + DataOutputStream output = null; + DataInputStream in = null; + BufferedReader is = null; + HttpURLConnection conn =null; + try { + + //transaction = "requestType=BACKEND&merchant_id=300200260&trnType=P&username=carlito&password=shopizer001&orderNumber=caa71106-7e3f-4975-a657-a35904dc32a0&trnCardOwner=Carl Samson&trnCardNumber=5100000020002000&trnExpMonth=10&trnExpYear=14&trnCardCvd=123&trnAmount=77.01&ordName=Carl S&ordAddress1=358 Du Languedoc&ordCity=Victoria&ordProvince=BC&ordPostalCode=V8T2E7&ordCountry=CA&ordPhoneNumber=(444) 555-6666&ordEmailAddress=csamson777@yahoo.com"; + /** + requestType=BACKEND&merchant_id=300200260 + &trnType=P + &username=carlito&password=shopizer001 + &orderNumber=caa71106-7e3f-4975-a657-a35904dc32a0 + &trnCardOwner=Carl Samson + &trnCardNumber=5100000020002000 + &trnExpMonth=10 + &trnExpYear=14 + &trnCardCvd=123 + &trnAmount=77.01 + &ordName=Carl S + &ordAddress1=378 Du Languedoc + &ordCity=Boucherville + &ordProvince=QC + &ordPostalCode=J3B8J1 + &ordCountry=CA + &ordPhoneNumber=(444) 555-6666 + &ordEmailAddress=test@yahoo.com + **/ + + /** + merchant_id=123456789&requestType=BACKEND + &trnType=P&trnOrderNumber=1234TEST&trnAmount=5.00&trnCardOwner=Joe+Test + &trnCardNumber=4030000010001234 + &trnExpMonth=10 + &trnExpYear=16 + &ordName=Joe+Test + &ordAddress1=123+Test+Street + &ordCity=Victoria + &ordProvince=BC + &ordCountry=CA + &ordPostalCode=V8T2E7 + &ordPhoneNumber=5555555555 + &ordEmailAddress=joe%40testemail.com + **/ + + + + boolean bSandbox = false; + if (configuration.getEnvironment().equals("TEST")) {// sandbox + bSandbox = true; + } + + String server = ""; + + ModuleConfig configs = module.getModuleConfigs().get("PROD"); + + if (bSandbox) { + configs = module.getModuleConfigs().get("TEST"); + } + + if(configs==null) { + throw new IntegrationException("Module not configured for TEST or PROD"); + } + + + server = new StringBuffer().append( + + configs.getScheme()).append("://") + .append(configs.getHost()) + .append(":") + .append(configs.getPort()) + .append(configs.getUri()).toString(); + + + + URL postURL = new URL(server); + conn = (HttpURLConnection) postURL.openConnection(); + + + // Set connection parameters. We need to perform input and output, + // so set both as true. + conn.setDoInput(true); + conn.setDoOutput(true); + + // Set the content type we are POSTing. We impersonate it as + // encoded form data + conn.setRequestProperty("Content-Type", + "application/x-www-form-urlencoded"); + conn.setRequestProperty("User-Agent", agent); + + conn.setRequestProperty("Content-Length", String + .valueOf(transaction.length())); + conn.setRequestMethod("POST"); + + // get the output stream to POST to. + output = new DataOutputStream(conn.getOutputStream()); + output.writeBytes(transaction); + output.flush(); + + + // Read input from the input stream. + in = new DataInputStream(conn.getInputStream()); + int rc = conn.getResponseCode(); + if (rc != -1) { + is = new BufferedReader(new InputStreamReader(conn + .getInputStream())); + String _line = null; + while (((_line = is.readLine()) != null)) { + respText = respText + _line; + } + + LOGGER.debug("BeanStream response -> " + respText.trim()); + + nvp = formatUrlResponse(respText.trim()); + } else { + throw new IntegrationException("Invalid response from BeanStream, return code is " + rc); + } + + //check + //trnApproved=1&trnId=10003067&messageId=1&messageText=Approved&trnOrderNumber=E40089&authCode=TEST&errorType=N&errorFields= + + String transactionApproved = nvp.get("TRNAPPROVED"); + String transactionId = nvp.get("TRNID"); + String messageId = nvp.get("MESSAGEID"); + String messageText = (String)nvp.get("MESSAGETEXT"); + String orderId = (String)nvp.get("TRNORDERNUMBER"); + String authCode = (String)nvp.get("AUTHCODE"); + String errorType = (String)nvp.get("ERRORTYPE"); + String errorFields = (String)nvp.get("ERRORFIELDS"); + if(!StringUtils.isBlank(orderNumber)) { + nvp.put("INTERNALORDERID", orderNumber); + } + + if(StringUtils.isBlank(transactionApproved)) { + throw new IntegrationException("Required field transactionApproved missing from BeanStream response"); + } + + //errors + if(transactionApproved.equals("0")) { + + merchantLogService.save( + new MerchantLog(store, + "Can't process BeanStream message " + + messageText + " return code id " + messageId)); + + IntegrationException te = new IntegrationException( + "Can't process BeanStream message " + messageText); + te.setExceptionType(IntegrationException.EXCEPTION_PAYMENT_DECLINED); + te.setMessageCode("message.payment.beanstream." + messageId); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + //create transaction object + + //return parseResponse(type,transaction,respText,nvp,order); + return this.parseResponse(transactionType, paymentType, nvp, amount); + + + } catch(Exception e) { + if(e instanceof IntegrationException) { + throw (IntegrationException)e; + } + + throw new IntegrationException("Error while processing BeanStream transaction",e); + + } finally { + if (is != null) { + try { + is.close(); + } catch (Exception ignore) { + // TODO: handle exception + } + } + + if (in != null) { + try { + in.close(); + } catch (Exception ignore) { + // TODO: handle exception + } + } + + if (output != null) { + try { + output.close(); + } catch (Exception ignore) { + // TODO: handle exception + } + } + + if (conn != null) { + try { + conn.disconnect(); + } catch (Exception ignore) { + // TODO: handle exception + } + } + + } + + + } + + + + private Transaction processTransaction(MerchantStore store, Customer customer, TransactionType type, + BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) throws IntegrationException { + + + + + + boolean bSandbox = false; + if (configuration.getEnvironment().equals("TEST")) {// sandbox + bSandbox = true; + } + + ModuleConfig configs = module.getModuleConfigs().get("PROD"); + + if (bSandbox) { + configs = module.getModuleConfigs().get("TEST"); + } + + if(configs==null) { + throw new IntegrationException("Module not configured for TEST or PROD"); + } + + + String server = new StringBuffer().append( + + configs.getScheme()).append("://") + .append(configs.getHost()) + .append(":") + .append(configs.getPort()) + .append(configs.getUri()).toString(); + + HttpURLConnection conn = null; + + try { + + String uniqueId = UUID.randomUUID().toString();//TODO + + String orderNumber = uniqueId; + + String amnt = productPriceUtils.getAdminFormatedAmount(store, amount); + + + StringBuilder messageString = new StringBuilder(); + + String transactionType = "P"; + if(type == TransactionType.AUTHORIZE) { + transactionType = "PA"; + } else if(type == TransactionType.AUTHORIZECAPTURE) { + transactionType = "P"; + } + + CreditCardPayment creditCardPayment = (CreditCardPayment)payment; + + messageString.append("requestType=BACKEND&"); + messageString.append("merchant_id=").append(configuration.getIntegrationKeys().get("merchantid")).append("&"); + messageString.append("trnType=").append(transactionType).append("&"); + messageString.append("username=").append(configuration.getIntegrationKeys().get("username")).append("&"); + messageString.append("password=").append(configuration.getIntegrationKeys().get("password")).append("&"); + messageString.append("orderNumber=").append(orderNumber).append("&"); + messageString.append("trnCardOwner=").append(creditCardPayment.getCardOwner()).append("&"); + messageString.append("trnCardNumber=").append(creditCardPayment.getCreditCardNumber()).append("&"); + messageString.append("trnExpMonth=").append(creditCardPayment.getExpirationMonth()).append("&"); + messageString.append("trnExpYear=").append(creditCardPayment.getExpirationYear().substring(2)).append("&"); + messageString.append("trnCardCvd=").append(creditCardPayment.getCredidCardValidationNumber()).append("&"); + messageString.append("trnAmount=").append(amnt).append("&"); + + StringBuilder nm = new StringBuilder(); + nm.append(customer.getBilling().getFirstName()).append(" ").append(customer.getBilling().getLastName()); + + + messageString.append("ordName=").append(nm.toString()).append("&"); + messageString.append("ordAddress1=").append(customer.getBilling().getAddress()).append("&"); + messageString.append("ordCity=").append(customer.getBilling().getCity()).append("&"); + + String stateProvince = customer.getBilling().getState(); + if(customer.getBilling().getZone()!=null) { + stateProvince = customer.getBilling().getZone().getCode(); + } + + String countryName = customer.getBilling().getCountry().getIsoCode(); + + messageString.append("ordProvince=").append(stateProvince).append("&"); + messageString.append("ordPostalCode=").append(customer.getBilling().getPostalCode().replaceAll("\\s","")).append("&"); + messageString.append("ordCountry=").append(countryName).append("&"); + messageString.append("ordPhoneNumber=").append(customer.getBilling().getTelephone()).append("&"); + messageString.append("ordEmailAddress=").append(customer.getEmailAddress()); + + + + + /** + * purchase (P) + * ----------- + REQUEST -> merchant_id=123456789&requestType=BACKEND&trnType=P&trnOrderNumber=1234TEST&trnAmount=5.00&trnCardOwner=Joe+Test&trnCardNumber=4030000010001234&trnExpMonth=10&trnExpYear=10&ordName=Joe+Test&ordAddress1=123+Test+Street&ordCity=Victoria&ordProvince=BC&ordCountry=CA&ordPostalCode=V8T2E7&ordPhoneNumber=5555555555&ordEmailAddress=joe%40testemail.com + RESPONSE-> trnApproved=1&trnId=10003067&messageId=1&messageText=Approved&trnOrderNumber=E40089&authCode=TEST&errorType=N&errorFields=&responseType=T&trnAmount=10%2E00&trnDate=1%2F17%2F2008+11%3A36%3A34+AM&avsProcessed=0&avsId=0&avsResult=0&avsAddrMatch=0&avsPostalMatch=0&avsMessage=Address+Verification+not+performed+for+this+transaction%2E&rspCodeCav=0&rspCavResult=0&rspCodeCredit1=0&rspCodeCredit2=0&rspCodeCredit3=0&rspCodeCredit4=0&rspCodeAddr1=0&rspCodeAddr2=0&rspCodeAddr3=0&rspCodeAddr4=0&rspCodeDob=0&rspCustomerDec=&trnType=P&paymentMethod=CC&ref1=&ref2=&ref3=&ref4=&ref5= + + pre authorization (PA) + ---------------------- + + Prior to processing a pre-authorization through the API, you must modify the transaction settings in your Beanstream merchant member area to allow for this transaction type. + - Log in to the Beanstream online member area at www.beanstream.com/admin/sDefault.asp. + - Navigate to administration - account admin - order settings in the left menu. + Under the heading �Restrict Internet Transaction Processing Types,� select either of the last two options. The �Purchases or Pre-Authorization Only� option will allow you to process both types of transaction through your web interface. De-selecting the �Restrict Internet Transaction Processing Types� checkbox will allow you to process all types of transactions including returns, voids and pre-auth completions. + + capture (PAC) -> requires trnId + ------------- + + refund (R) + ------------- + REQUEST -> merchant_id=123456789&requestType=BACKEND&trnType=R&username=user1234&password=pass1234&trnOrderNumber=1234&trnAmount=1.00&adjId=10002115 + RESPONSE-> trnApproved=1&trnId=10002118&messageId=1&messageText=Approved&trnOrderNumber=1234R&authCode=TEST&errorType=N&errorFields=&responseType=T&trnAmount=1%2E00&trnDate=8%2F17%2F2009+1%3A44%3A56+PM&avsProcessed=0&avsId=0&avsResult=0&avsAddrMatch=0&avsPostalMatch=0&avsMessage=Address+Verification+not+performed+for+this+transaction%2E&cardType=VI&trnType=R&paymentMethod=CC&ref1=&ref2=&ref3=&ref4=&ref5= + + + //notes + //On receipt of the transaction response, the merchant must display order amount, transaction ID number, bank authorization code (authCode), currency, date and �messageText� to the customer on a confirmation page. + */ + + + //String agent = "Mozilla/4.0"; + //String respText = ""; + //Map nvp = null; + + + /** debug **/ + + + + StringBuilder messageLogString = new StringBuilder(); + + + messageLogString.append("requestType=BACKEND&"); + messageLogString.append("merchant_id=").append(configuration.getIntegrationKeys().get("merchantid")).append("&"); + messageLogString.append("trnType=").append(type).append("&"); + messageLogString.append("orderNumber=").append(orderNumber).append("&"); + messageLogString.append("trnCardOwner=").append(creditCardPayment.getCardOwner()).append("&"); + messageLogString.append("trnCardNumber=").append(CreditCardUtils.maskCardNumber(creditCardPayment.getCreditCardNumber())).append("&"); + messageLogString.append("trnExpMonth=").append(creditCardPayment.getExpirationMonth()).append("&"); + messageLogString.append("trnExpYear=").append(creditCardPayment.getExpirationYear()).append("&"); + messageLogString.append("trnCardCvd=").append(creditCardPayment.getCredidCardValidationNumber()).append("&"); + messageLogString.append("trnAmount=").append(amnt).append("&"); + + messageLogString.append("ordName=").append(nm.toString()).append("&"); + messageLogString.append("ordAddress1=").append(customer.getBilling().getAddress()).append("&"); + messageLogString.append("ordCity=").append(customer.getBilling().getCity()).append("&"); + + + + messageLogString.append("ordProvince=").append(stateProvince).append("&"); + messageLogString.append("ordPostalCode=").append(customer.getBilling().getPostalCode()).append("&"); + messageLogString.append("ordCountry=").append(customer.getBilling().getCountry().getName()).append("&"); + messageLogString.append("ordPhoneNumber=").append(customer.getBilling().getTelephone()).append("&"); + messageLogString.append("ordEmailAddress=").append(customer.getEmailAddress()); + + + + + /** debug **/ + + + LOGGER.debug("REQUEST SENT TO BEANSTREAM -> " + messageLogString.toString()); + + + URL postURL = new URL(server); + conn = (HttpURLConnection) postURL.openConnection(); + + + + return sendTransaction(orderNumber, store, messageString.toString(), transactionType, type, payment.getPaymentType(), amount, configuration, module); + + } catch(Exception e) { + + if(e instanceof IntegrationException) + throw (IntegrationException)e; + throw new IntegrationException("Error while processing BeanStream transaction",e); + + } finally { + + + if (conn != null) { + try { + conn.disconnect(); + } catch (Exception ignore) {} + } + } + + } + + + + private Transaction parseResponse(TransactionType transactionType, + PaymentType paymentType, Map nvp, + BigDecimal amount) throws Exception { + + + Transaction transaction = new Transaction(); + transaction.setAmount(amount); + //transaction.setOrder(order); + transaction.setTransactionDate(new Date()); + transaction.setTransactionType(transactionType); + transaction.setPaymentType(PaymentType.CREDITCARD); + transaction.getTransactionDetails().put("TRANSACTIONID", (String)nvp.get("TRNID")); + transaction.getTransactionDetails().put("TRNAPPROVED", (String)nvp.get("TRNAPPROVED")); + transaction.getTransactionDetails().put("TRNORDERNUMBER", (String)nvp.get("TRNORDERNUMBER")); + transaction.getTransactionDetails().put("MESSAGETEXT", (String)nvp.get("MESSAGETEXT")); + if(nvp.get("INTERNALORDERID")!=null) { + transaction.getTransactionDetails().put("INTERNALORDERID", (String)nvp.get("INTERNALORDERID")); + } + return transaction; + + } + + private Map formatUrlResponse(String payload) throws Exception { + HashMap nvp = new HashMap (); + StringTokenizer stTok = new StringTokenizer(payload, "&"); + while (stTok.hasMoreTokens()) { + StringTokenizer stInternalTokenizer = new StringTokenizer(stTok + .nextToken(), "="); + if (stInternalTokenizer.countTokens() == 2) { + String key = URLDecoder.decode(stInternalTokenizer.nextToken(), + "UTF-8"); + String value = URLDecoder.decode(stInternalTokenizer + .nextToken(), "UTF-8"); + nvp.put(key.toUpperCase(), value); + } + } + return nvp; + } + + @Override + public void validateModuleConfiguration( + IntegrationConfiguration integrationConfiguration, + MerchantStore store) throws IntegrationException { + + + List errorFields = null; + + + Map keys = integrationConfiguration.getIntegrationKeys(); + + //validate integrationKeys['merchantid'] + if(keys==null || StringUtils.isBlank(keys.get("merchantid"))) { + errorFields = new ArrayList(); + errorFields.add("merchantid"); + } + + //validate integrationKeys['username'] + if(keys==null || StringUtils.isBlank(keys.get("username"))) { + if(errorFields==null) { + errorFields = new ArrayList(); + } + errorFields.add("username"); + } + + + //validate integrationKeys['password'] + if(keys==null || StringUtils.isBlank(keys.get("password"))) { + if(errorFields==null) { + errorFields = new ArrayList(); + } + errorFields.add("password"); + } + + + + if(errorFields!=null) { + IntegrationException ex = new IntegrationException(IntegrationException.ERROR_VALIDATION_SAVE); + ex.setErrorFields(errorFields); + throw ex; + + } + + + + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/BraintreePayment.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/BraintreePayment.java new file mode 100755 index 0000000000..0786bbf926 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/BraintreePayment.java @@ -0,0 +1,469 @@ +package com.salesmanager.core.business.modules.integration.payment.impl; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; + +import com.braintreegateway.BraintreeGateway; +import com.braintreegateway.Environment; +import com.braintreegateway.Result; +import com.braintreegateway.TransactionRequest; +import com.braintreegateway.ValidationError; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.payments.Payment; +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.payments.TransactionType; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.modules.integration.IntegrationException; +import com.salesmanager.core.modules.integration.payment.model.PaymentModule; + +public class BraintreePayment implements PaymentModule { + + @Override + public void validateModuleConfiguration(IntegrationConfiguration integrationConfiguration, MerchantStore store) + throws IntegrationException { + List errorFields = null; + + + Map keys = integrationConfiguration.getIntegrationKeys(); + + //validate integrationKeys['merchant_id'] + if(keys==null || StringUtils.isBlank(keys.get("merchant_id"))) { + errorFields = new ArrayList(); + errorFields.add("merchant_id"); + } + + //validate integrationKeys['public_key'] + if(keys==null || StringUtils.isBlank(keys.get("public_key"))) { + if(errorFields==null) { + errorFields = new ArrayList(); + } + errorFields.add("public_key"); + } + + //validate integrationKeys['private_key'] + if(keys==null || StringUtils.isBlank(keys.get("private_key"))) { + if(errorFields==null) { + errorFields = new ArrayList(); + } + errorFields.add("private_key"); + } + + //validate integrationKeys['tokenization_key'] + if(keys==null || StringUtils.isBlank(keys.get("tokenization_key"))) { + if(errorFields==null) { + errorFields = new ArrayList(); + } + errorFields.add("tokenization_key"); + } + + + if(errorFields!=null) { + IntegrationException ex = new IntegrationException(IntegrationException.ERROR_VALIDATION_SAVE); + ex.setErrorFields(errorFields); + throw ex; + + } + + } + + @Override + public Transaction initTransaction(MerchantStore store, Customer customer, BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) throws IntegrationException { + + Validate.notNull(configuration,"Configuration cannot be null"); + + String merchantId = configuration.getIntegrationKeys().get("merchant_id"); + String publicKey = configuration.getIntegrationKeys().get("public_key"); + String privateKey = configuration.getIntegrationKeys().get("private_key"); + + Validate.notNull(merchantId,"merchant_id cannot be null"); + Validate.notNull(publicKey,"public_key cannot be null"); + Validate.notNull(privateKey,"private_key cannot be null"); + + Environment environment= Environment.PRODUCTION; + if (configuration.getEnvironment().equals("TEST")) {// sandbox + environment= Environment.SANDBOX; + } + + BraintreeGateway gateway = new BraintreeGateway( + environment, + merchantId, + publicKey, + privateKey + ); + + String clientToken = gateway.clientToken().generate(); + + Transaction transaction = new Transaction(); + transaction.setAmount(amount); + transaction.setDetails(clientToken); + transaction.setPaymentType(payment.getPaymentType()); + transaction.setTransactionDate(new Date()); + transaction.setTransactionType(payment.getTransactionType()); + + return transaction; + } + + @Override + public Transaction authorize(MerchantStore store, Customer customer, List items, + BigDecimal amount, Payment payment, IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + + Validate.notNull(configuration,"Configuration cannot be null"); + + String merchantId = configuration.getIntegrationKeys().get("merchant_id"); + String publicKey = configuration.getIntegrationKeys().get("public_key"); + String privateKey = configuration.getIntegrationKeys().get("private_key"); + + Validate.notNull(merchantId,"merchant_id cannot be null"); + Validate.notNull(publicKey,"public_key cannot be null"); + Validate.notNull(privateKey,"private_key cannot be null"); + + String nonce = payment.getPaymentMetaData().get("paymentToken"); + + if(StringUtils.isBlank(nonce)) { + IntegrationException te = new IntegrationException( + "Can't process Braintree, missing authorization nounce"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + Environment environment= Environment.PRODUCTION; + if (configuration.getEnvironment().equals("TEST")) {// sandbox + environment= Environment.SANDBOX; + } + + BraintreeGateway gateway = new BraintreeGateway( + environment, + merchantId, + publicKey, + privateKey + ); + + + + TransactionRequest request = new TransactionRequest() + .amount(amount) + .paymentMethodNonce(nonce); + + Result result = gateway.transaction().sale(request); + + String authorizationId = null; + + if (result.isSuccess()) { + com.braintreegateway.Transaction transaction = result.getTarget(); + authorizationId = transaction.getId(); + } else if (result.getTransaction() != null) { + com.braintreegateway.Transaction transaction = result.getTransaction(); + authorizationId = transaction.getAuthorizedTransactionId(); + } else { + String errorString = ""; + for (ValidationError error : result.getErrors().getAllDeepValidationErrors()) { + errorString += "Error: " + error.getCode() + ": " + error.getMessage() + "\n"; + } + + IntegrationException te = new IntegrationException( + "Can't process Braintree authorization " + errorString); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + + } + + if(StringUtils.isBlank(authorizationId)) { + IntegrationException te = new IntegrationException( + "Can't process Braintree, missing authorizationId"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + Transaction trx = new Transaction(); + trx.setAmount(amount); + trx.setTransactionDate(new Date()); + trx.setTransactionType(TransactionType.AUTHORIZE); + trx.setPaymentType(PaymentType.CREDITCARD); + trx.getTransactionDetails().put("TRANSACTIONID", authorizationId); + trx.getTransactionDetails().put("TRNAPPROVED", null); + trx.getTransactionDetails().put("TRNORDERNUMBER", authorizationId); + trx.getTransactionDetails().put("MESSAGETEXT", null); + + return trx; + + } + + @Override + public Transaction capture(MerchantStore store, Customer customer, Order order, Transaction capturableTransaction, + IntegrationConfiguration configuration, IntegrationModule module) throws IntegrationException { + Validate.notNull(configuration,"Configuration cannot be null"); + + String merchantId = configuration.getIntegrationKeys().get("merchant_id"); + String publicKey = configuration.getIntegrationKeys().get("public_key"); + String privateKey = configuration.getIntegrationKeys().get("private_key"); + + Validate.notNull(merchantId,"merchant_id cannot be null"); + Validate.notNull(publicKey,"public_key cannot be null"); + Validate.notNull(privateKey,"private_key cannot be null"); + + String auth = capturableTransaction.getTransactionDetails().get("TRANSACTIONID"); + + if(StringUtils.isBlank(auth)) { + IntegrationException te = new IntegrationException( + "Can't process Braintree, missing authorization id"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + Environment environment= Environment.PRODUCTION; + if (configuration.getEnvironment().equals("TEST")) {// sandbox + environment= Environment.SANDBOX; + } + + BraintreeGateway gateway = new BraintreeGateway( + environment, + merchantId, + publicKey, + privateKey + ); + + + BigDecimal amount = order.getTotal(); + + Result result = gateway.transaction().submitForSettlement(auth, amount); + + String trxId = null; + + if (result.isSuccess()) { + com.braintreegateway.Transaction settledTransaction = result.getTarget(); + trxId = settledTransaction.getId(); + } else { + String errorString = ""; + for (ValidationError error : result.getErrors().getAllDeepValidationErrors()) { + errorString += "Error: " + error.getCode() + ": " + error.getMessage() + "\n"; + } + + IntegrationException te = new IntegrationException( + "Can't process Braintree refund " + errorString); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + + } + + if(StringUtils.isBlank(trxId)) { + IntegrationException te = new IntegrationException( + "Can't process Braintree, missing original transaction"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + Transaction trx = new Transaction(); + trx.setAmount(amount); + trx.setTransactionDate(new Date()); + trx.setTransactionType(TransactionType.CAPTURE); + trx.setPaymentType(PaymentType.CREDITCARD); + trx.getTransactionDetails().put("TRANSACTIONID", trxId); + trx.getTransactionDetails().put("TRNAPPROVED", null); + trx.getTransactionDetails().put("TRNORDERNUMBER", trxId); + trx.getTransactionDetails().put("MESSAGETEXT", null); + + return trx; + + + } + + @Override + public Transaction authorizeAndCapture(MerchantStore store, Customer customer, List items, + BigDecimal amount, Payment payment, IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + Validate.notNull(configuration,"Configuration cannot be null"); + + String merchantId = configuration.getIntegrationKeys().get("merchant_id"); + String publicKey = configuration.getIntegrationKeys().get("public_key"); + String privateKey = configuration.getIntegrationKeys().get("private_key"); + + Validate.notNull(merchantId,"merchant_id cannot be null"); + Validate.notNull(publicKey,"public_key cannot be null"); + Validate.notNull(privateKey,"private_key cannot be null"); + + String nonce = payment.getPaymentMetaData().get("paymentToken");//paymentToken + + if(StringUtils.isBlank(nonce)) { + IntegrationException te = new IntegrationException( + "Can't process Braintree, missing authorization nounce"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + Environment environment= Environment.PRODUCTION; + if (configuration.getEnvironment().equals("TEST")) {// sandbox + environment= Environment.SANDBOX; + } + + BraintreeGateway gateway = new BraintreeGateway( + environment, + merchantId, + publicKey, + privateKey + ); + + + + TransactionRequest request = new TransactionRequest() + .amount(amount) + .paymentMethodNonce(nonce); + + Result result = gateway.transaction().sale(request); + + String trxId = null; + + if (result.isSuccess()) { + com.braintreegateway.Transaction transaction = result.getTarget(); + trxId = transaction.getId(); + } else { + String errorString = ""; + for (ValidationError error : result.getErrors().getAllDeepValidationErrors()) { + errorString += "Error: " + error.getCode() + ": " + error.getMessage() + "\n"; + } + + IntegrationException te = new IntegrationException( + "Can't process Braintree auth + capture " + errorString); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + + } + + if(StringUtils.isBlank(trxId)) { + IntegrationException te = new IntegrationException( + "Can't process Braintree, missing trxId"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + Transaction trx = new Transaction(); + trx.setAmount(amount); + trx.setTransactionDate(new Date()); + trx.setTransactionType(TransactionType.AUTHORIZECAPTURE); + trx.setPaymentType(PaymentType.CREDITCARD); + trx.getTransactionDetails().put("TRANSACTIONID", trxId); + trx.getTransactionDetails().put("TRNAPPROVED", null); + trx.getTransactionDetails().put("TRNORDERNUMBER", trxId); + trx.getTransactionDetails().put("MESSAGETEXT", null); + + return trx; + + + } + + @Override + public Transaction refund(boolean partial, MerchantStore store, Transaction transaction, Order order, + BigDecimal amount, IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + + String merchantId = configuration.getIntegrationKeys().get("merchant_id"); + String publicKey = configuration.getIntegrationKeys().get("public_key"); + String privateKey = configuration.getIntegrationKeys().get("private_key"); + + Validate.notNull(merchantId,"merchant_id cannot be null"); + Validate.notNull(publicKey,"public_key cannot be null"); + Validate.notNull(privateKey,"private_key cannot be null"); + + String auth = transaction.getTransactionDetails().get("TRANSACTIONID"); + + if(StringUtils.isBlank(auth)) { + IntegrationException te = new IntegrationException( + "Can't process Braintree refund, missing transaction id"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + Environment environment= Environment.PRODUCTION; + if (configuration.getEnvironment().equals("TEST")) {// sandbox + environment= Environment.SANDBOX; + } + + BraintreeGateway gateway = new BraintreeGateway( + environment, + merchantId, + publicKey, + privateKey + ); + + + Result result = gateway.transaction().refund(auth, amount); + + String trxId = null; + + if (result.isSuccess()) { + com.braintreegateway.Transaction settledTransaction = result.getTarget(); + trxId = settledTransaction.getId(); + } else { + String errorString = ""; + for (ValidationError error : result.getErrors().getAllDeepValidationErrors()) { + errorString += "Error: " + error.getCode() + ": " + error.getMessage() + "\n"; + } + + IntegrationException te = new IntegrationException( + "Can't process Braintree refund " + errorString); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + + } + + if(StringUtils.isBlank(trxId)) { + IntegrationException te = new IntegrationException( + "Can't process Braintree refund, missing original transaction"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + Transaction trx = new Transaction(); + trx.setAmount(amount); + trx.setTransactionDate(new Date()); + trx.setTransactionType(TransactionType.REFUND); + trx.setPaymentType(PaymentType.CREDITCARD); + trx.getTransactionDetails().put("TRANSACTIONID", trxId); + trx.getTransactionDetails().put("TRNAPPROVED", null); + trx.getTransactionDetails().put("TRNORDERNUMBER", trxId); + trx.getTransactionDetails().put("MESSAGETEXT", null); + + return trx; + + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/MoneyOrderPayment.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/MoneyOrderPayment.java new file mode 100755 index 0000000000..2a01e71cc7 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/MoneyOrderPayment.java @@ -0,0 +1,113 @@ +package com.salesmanager.core.business.modules.integration.payment.impl; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; + +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.payments.Payment; +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.payments.TransactionType; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.modules.integration.IntegrationException; +import com.salesmanager.core.modules.integration.payment.model.PaymentModule; + +public class MoneyOrderPayment implements PaymentModule { + + @Override + public void validateModuleConfiguration( + IntegrationConfiguration integrationConfiguration, + MerchantStore store) throws IntegrationException { + + List errorFields = null; + + + Map keys = integrationConfiguration.getIntegrationKeys(); + + //validate integrationKeys['address'] + if(keys==null || StringUtils.isBlank(keys.get("address"))) { + errorFields = new ArrayList(); + errorFields.add("address"); + } + + if(errorFields!=null) { + IntegrationException ex = new IntegrationException(IntegrationException.ERROR_VALIDATION_SAVE); + ex.setErrorFields(errorFields); + throw ex; + } + } + + @Override + public Transaction initTransaction(MerchantStore store, Customer customer, + BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + //NOT REQUIRED + return null; + } + + @Override + public Transaction authorize(MerchantStore store, Customer customer, + List items, BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + //NOT REQUIRED + return null; + } + +/* @Override + public Transaction capture(MerchantStore store, Customer customer, + List items, BigDecimal amount, Payment payment, Transaction transaction, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + //NOT REQUIRED + return null; + }*/ + + @Override + public Transaction authorizeAndCapture(MerchantStore store, Customer customer, + List items, BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + + Transaction transaction = new Transaction(); + transaction.setAmount(amount); + transaction.setTransactionDate(new Date()); + transaction.setTransactionType(TransactionType.AUTHORIZECAPTURE); + transaction.setPaymentType(PaymentType.MONEYORDER); + + + return transaction; + + + + } + + @Override + public Transaction refund(boolean partial, MerchantStore store, Transaction transaction, + Order order, BigDecimal amount, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + throw new IntegrationException("Transaction not supported"); + } + + @Override + public Transaction capture(MerchantStore store, Customer customer, + Order order, Transaction capturableTransaction, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/PayPalExpressCheckoutPayment.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/PayPalExpressCheckoutPayment.java new file mode 100755 index 0000000000..03f01f72ec --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/PayPalExpressCheckoutPayment.java @@ -0,0 +1,670 @@ +package com.salesmanager.core.business.modules.integration.payment.impl; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.utils.CoreConfiguration; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.order.OrderTotal; +import com.salesmanager.core.model.order.OrderTotalSummary; +import com.salesmanager.core.model.payments.Payment; +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.payments.TransactionType; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.modules.integration.IntegrationException; +import com.salesmanager.core.modules.integration.payment.model.PaymentModule; + +import urn.ebay.api.PayPalAPI.DoCaptureReq; +import urn.ebay.api.PayPalAPI.DoCaptureRequestType; +import urn.ebay.api.PayPalAPI.DoCaptureResponseType; +import urn.ebay.api.PayPalAPI.DoExpressCheckoutPaymentReq; +import urn.ebay.api.PayPalAPI.DoExpressCheckoutPaymentRequestType; +import urn.ebay.api.PayPalAPI.DoExpressCheckoutPaymentResponseType; +import urn.ebay.api.PayPalAPI.GetExpressCheckoutDetailsReq; +import urn.ebay.api.PayPalAPI.GetExpressCheckoutDetailsRequestType; +import urn.ebay.api.PayPalAPI.GetExpressCheckoutDetailsResponseType; +import urn.ebay.api.PayPalAPI.PayPalAPIInterfaceServiceService; +import urn.ebay.api.PayPalAPI.RefundTransactionReq; +import urn.ebay.api.PayPalAPI.RefundTransactionRequestType; +import urn.ebay.api.PayPalAPI.RefundTransactionResponseType; +import urn.ebay.api.PayPalAPI.SetExpressCheckoutReq; +import urn.ebay.api.PayPalAPI.SetExpressCheckoutRequestType; +import urn.ebay.api.PayPalAPI.SetExpressCheckoutResponseType; +import urn.ebay.apis.CoreComponentTypes.BasicAmountType; +import urn.ebay.apis.eBLBaseComponents.CompleteCodeType; +import urn.ebay.apis.eBLBaseComponents.DoExpressCheckoutPaymentRequestDetailsType; +import urn.ebay.apis.eBLBaseComponents.PaymentDetailsItemType; +import urn.ebay.apis.eBLBaseComponents.PaymentDetailsType; +import urn.ebay.apis.eBLBaseComponents.PaymentInfoType; +import urn.ebay.apis.eBLBaseComponents.RefundType; +import urn.ebay.apis.eBLBaseComponents.SetExpressCheckoutRequestDetailsType; + +public class PayPalExpressCheckoutPayment implements PaymentModule { + + private static final Logger LOGGER = LoggerFactory.getLogger(PayPalExpressCheckoutPayment.class); + + + @Inject + private PricingService pricingService; + + @Inject + private CoreConfiguration coreConfiguration; + + @Override + public void validateModuleConfiguration( + IntegrationConfiguration integrationConfiguration, + MerchantStore store) throws IntegrationException { + + + List errorFields = null; + + //validate integrationKeys['account'] + Map keys = integrationConfiguration.getIntegrationKeys(); + if(keys==null || StringUtils.isBlank(keys.get("api"))) { + errorFields = new ArrayList(); + errorFields.add("api"); + } + + if(keys==null || StringUtils.isBlank(keys.get("username"))) { + if(errorFields==null) { + errorFields = new ArrayList(); + } + errorFields.add("username"); + } + + if(keys==null || StringUtils.isBlank(keys.get("signature"))) { + if(errorFields==null) { + errorFields = new ArrayList(); + } + errorFields.add("signature"); + } + + + if(errorFields!=null) { + IntegrationException ex = new IntegrationException(IntegrationException.ERROR_VALIDATION_SAVE); + ex.setErrorFields(errorFields); + throw ex; + + } + + + } + + @Override + public Transaction initTransaction(MerchantStore store, Customer customer, + BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + throw new IntegrationException("Not imlemented"); + } + + @Override + public Transaction authorize(MerchantStore store, Customer customer, + List items, BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + + com.salesmanager.core.model.payments.PaypalPayment paypalPayment = (com.salesmanager.core.model.payments.PaypalPayment)payment; + Validate.notNull(paypalPayment.getPaymentToken(), "A paypal payment token is required to process this transaction"); + + return processTransaction(store, customer, items, amount, paypalPayment, configuration, module); + + + } + +/* @Override + public Transaction capture(MerchantStore store, Customer customer, + List items, BigDecimal amount, Payment payment, Transaction transaction, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + com.salesmanager.core.business.payments.model.PaypalPayment paypalPayment = (com.salesmanager.core.business.payments.model.PaypalPayment)payment; + Validate.notNull(paypalPayment.getPaymentToken(), "A paypal payment token is required to process this transaction"); + + return processTransaction(store, customer, items, amount, paypalPayment, configuration, module); + + }*/ + + public Transaction initPaypalTransaction(MerchantStore store, + List items, OrderTotalSummary summary, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + Validate.notNull(configuration, "Configuration must not be null"); + Validate.notNull(payment, "Payment must not be null"); + Validate.notNull(summary, "OrderTotalSummary must not be null"); + + + try { + + + PaymentDetailsType paymentDetails = new PaymentDetailsType(); + if(configuration.getIntegrationKeys().get("transaction").equalsIgnoreCase(TransactionType.AUTHORIZECAPTURE.name())) { + paymentDetails.setPaymentAction(urn.ebay.apis.eBLBaseComponents.PaymentActionCodeType.SALE); + } else { + paymentDetails.setPaymentAction(urn.ebay.apis.eBLBaseComponents.PaymentActionCodeType.AUTHORIZATION); + } + + + List lineItems = new ArrayList(); + + for(ShoppingCartItem cartItem : items) { + + PaymentDetailsItemType item = new PaymentDetailsItemType(); + BasicAmountType amt = new BasicAmountType(); + amt.setCurrencyID(urn.ebay.apis.eBLBaseComponents.CurrencyCodeType.fromValue(payment.getCurrency().getCode())); + amt.setValue(pricingService.getStringAmount(cartItem.getFinalPrice().getFinalPrice(), store)); + //itemsTotal = itemsTotal.add(cartItem.getSubTotal()); + int itemQuantity = cartItem.getQuantity(); + item.setQuantity(itemQuantity); + item.setName(cartItem.getProduct().getProductDescription().getName()); + item.setAmount(amt); + //System.out.println(pricingService.getStringAmount(cartItem.getSubTotal(), store)); + lineItems.add(item); + + } + + + List orderTotals = summary.getTotals(); + BigDecimal tax = null; + for(OrderTotal total : orderTotals) { + + if(total.getModule().equals(Constants.OT_SHIPPING_MODULE_CODE)) { + BasicAmountType shipping = new BasicAmountType(); + shipping.setCurrencyID(urn.ebay.apis.eBLBaseComponents.CurrencyCodeType.fromValue(store.getCurrency().getCode())); + shipping.setValue(pricingService.getStringAmount(total.getValue(), store)); + //System.out.println(pricingService.getStringAmount(total.getValue(), store)); + paymentDetails.setShippingTotal(shipping); + } + + if(total.getModule().equals(Constants.OT_HANDLING_MODULE_CODE)) { + BasicAmountType handling = new BasicAmountType(); + handling.setCurrencyID(urn.ebay.apis.eBLBaseComponents.CurrencyCodeType.fromValue(store.getCurrency().getCode())); + handling.setValue(pricingService.getStringAmount(total.getValue(), store)); + //System.out.println(pricingService.getStringAmount(total.getValue(), store)); + paymentDetails.setHandlingTotal(handling); + } + + if(total.getModule().equals(Constants.OT_TAX_MODULE_CODE)) { + if(tax==null) { + tax = new BigDecimal("0"); + } + tax = tax.add(total.getValue()); + } + + } + + if(tax!=null) { + BasicAmountType taxAmnt = new BasicAmountType(); + taxAmnt.setCurrencyID(urn.ebay.apis.eBLBaseComponents.CurrencyCodeType.fromValue(store.getCurrency().getCode())); + taxAmnt.setValue(pricingService.getStringAmount(tax, store)); + //System.out.println(pricingService.getStringAmount(tax, store)); + paymentDetails.setTaxTotal(taxAmnt); + } + + + + BasicAmountType itemTotal = new BasicAmountType(); + itemTotal.setCurrencyID(urn.ebay.apis.eBLBaseComponents.CurrencyCodeType.fromValue(store.getCurrency().getCode())); + itemTotal.setValue(pricingService.getStringAmount(summary.getSubTotal(), store)); + paymentDetails.setItemTotal(itemTotal); + + paymentDetails.setPaymentDetailsItem(lineItems); + BasicAmountType orderTotal = new BasicAmountType(); + orderTotal.setCurrencyID(urn.ebay.apis.eBLBaseComponents.CurrencyCodeType.fromValue(store.getCurrency().getCode())); + orderTotal.setValue(pricingService.getStringAmount(summary.getTotal(), store)); + //System.out.println(pricingService.getStringAmount(itemsTotal, store)); + paymentDetails.setOrderTotal(orderTotal); + List paymentDetailsList = new ArrayList(); + paymentDetailsList.add(paymentDetails); + + String baseScheme = store.getDomainName(); + String scheme = coreConfiguration.getProperty("SHOP_SCHEME"); + if(!StringUtils.isBlank(scheme)) { + baseScheme = new StringBuilder().append(coreConfiguration.getProperty("SHOP_SCHEME", "http")).append("://") + .append(store.getDomainName()).toString(); + } + + + + StringBuilder RETURN_URL = new StringBuilder(); + RETURN_URL.append( + baseScheme); + + if(!StringUtils.isBlank(baseScheme) && !baseScheme.endsWith(Constants.SLASH)) { + RETURN_URL.append(Constants.SLASH); + } + RETURN_URL.append(coreConfiguration.getProperty("CONTEXT_PATH", "sm-shop")); + + + + SetExpressCheckoutRequestDetailsType setExpressCheckoutRequestDetails = new SetExpressCheckoutRequestDetailsType(); + String returnUrl = RETURN_URL.toString() + new StringBuilder().append(Constants.SHOP_URI).append("/paypal/checkout").append(coreConfiguration.getProperty("URL_EXTENSION", ".html")).append("/success").toString(); + String cancelUrl = RETURN_URL.toString() + new StringBuilder().append(Constants.SHOP_URI).append("/paypal/checkout").append(coreConfiguration.getProperty("URL_EXTENSION", ".html")).append("/cancel").toString(); + + setExpressCheckoutRequestDetails.setReturnURL(returnUrl); + setExpressCheckoutRequestDetails.setCancelURL(cancelUrl); + + + setExpressCheckoutRequestDetails.setPaymentDetails(paymentDetailsList); + + SetExpressCheckoutRequestType setExpressCheckoutRequest = new SetExpressCheckoutRequestType(setExpressCheckoutRequestDetails); + setExpressCheckoutRequest.setVersion("104.0"); + + SetExpressCheckoutReq setExpressCheckoutReq = new SetExpressCheckoutReq(); + setExpressCheckoutReq.setSetExpressCheckoutRequest(setExpressCheckoutRequest); + + + String mode = "sandbox"; + String env = configuration.getEnvironment(); + if(Constants.PRODUCTION_ENVIRONMENT.equals(env)) { + mode = "production"; + } + + Map configurationMap = new HashMap(); + configurationMap.put("mode", mode); + configurationMap.put("acct1.UserName", configuration.getIntegrationKeys().get("username")); + configurationMap.put("acct1.Password", configuration.getIntegrationKeys().get("api")); + configurationMap.put("acct1.Signature", configuration.getIntegrationKeys().get("signature")); + + PayPalAPIInterfaceServiceService service = new PayPalAPIInterfaceServiceService(configurationMap); + SetExpressCheckoutResponseType setExpressCheckoutResponse = service.setExpressCheckout(setExpressCheckoutReq); + + String token = setExpressCheckoutResponse.getToken(); + String correlationID = setExpressCheckoutResponse.getCorrelationID(); + String ack = setExpressCheckoutResponse.getAck().getValue(); + + if(!"Success".equals(ack)) { + LOGGER.error("Wrong value from init transaction " + ack); + throw new IntegrationException("Wrong paypal ack from init transaction " + ack); + } + + Transaction transaction = new Transaction(); + transaction.setAmount(summary.getTotal()); + //transaction.setOrder(order); + transaction.setTransactionDate(new Date()); + transaction.setTransactionType(TransactionType.INIT); + transaction.setPaymentType(PaymentType.PAYPAL); + transaction.getTransactionDetails().put("TOKEN", token); + transaction.getTransactionDetails().put("CORRELATION", correlationID); + + + return transaction; + + //redirect user to + //https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-5LL13394G30048922 + + } catch(Exception e) { + e.printStackTrace(); + throw new IntegrationException(e); + } + + + } + + @Override + public Transaction authorizeAndCapture(MerchantStore store, + Customer customer, List items, BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + com.salesmanager.core.model.payments.PaypalPayment paypalPayment = (com.salesmanager.core.model.payments.PaypalPayment)payment; + Validate.notNull(paypalPayment.getPaymentToken(), "A paypal payment token is required to process this transaction"); + + return processTransaction(store, customer, items, amount, paypalPayment, configuration, module); + + + } + + @Override + public Transaction refund(boolean partial, MerchantStore store, + Transaction transaction, Order order, BigDecimal amount, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + + try { + + + + Validate.notNull(transaction,"Transaction cannot be null"); + Validate.notNull(transaction.getTransactionDetails().get("TRANSACTIONID"), "Transaction details must contain a TRANSACTIONID"); + Validate.notNull(order,"Order must not be null"); + Validate.notNull(order.getCurrency(),"Order nust contain Currency object"); + + String mode = "sandbox"; + String env = configuration.getEnvironment(); + if(Constants.PRODUCTION_ENVIRONMENT.equals(env)) { + mode = "production"; + } + + + RefundTransactionRequestType refundTransactionRequest = new RefundTransactionRequestType(); + refundTransactionRequest.setVersion("104.0"); + + RefundTransactionReq refundRequest = new RefundTransactionReq(); + refundRequest.setRefundTransactionRequest(refundTransactionRequest); + + + Map configurationMap = new HashMap(); + configurationMap.put("mode", mode); + configurationMap.put("acct1.UserName", configuration.getIntegrationKeys().get("username")); + configurationMap.put("acct1.Password", configuration.getIntegrationKeys().get("api")); + configurationMap.put("acct1.Signature", configuration.getIntegrationKeys().get("signature")); + + + PayPalAPIInterfaceServiceService service = new PayPalAPIInterfaceServiceService(configurationMap); + + + + RefundType refundType = RefundType.FULL; + if(partial) { + refundType = RefundType.PARTIAL; + } + + refundTransactionRequest.setRefundType(refundType); + + BasicAmountType refundAmount = new BasicAmountType(); + refundAmount.setValue(pricingService.getStringAmount(amount, store)); + refundAmount.setCurrencyID(urn.ebay.apis.eBLBaseComponents.CurrencyCodeType.fromValue(order.getCurrency().getCode())); + + refundTransactionRequest.setAmount(refundAmount); + refundTransactionRequest.setTransactionID(transaction.getTransactionDetails().get("TRANSACTIONID")); + + RefundTransactionResponseType refundTransactionResponse = service.refundTransaction(refundRequest); + + String refundAck = refundTransactionResponse.getAck().getValue(); + + + if(!"Success".equals(refundAck)) { + LOGGER.error("Wrong value from transaction commit " + refundAck); + throw new IntegrationException(ServiceException.EXCEPTION_TRANSACTION_DECLINED,"Paypal refund transaction code [" + refundTransactionResponse.getErrors().get(0).getErrorCode() + "], message-> " + refundTransactionResponse.getErrors().get(0).getShortMessage()); + } + + + Transaction newTransaction = new Transaction(); + newTransaction.setAmount(amount); + newTransaction.setTransactionDate(new Date()); + newTransaction.setTransactionType(TransactionType.REFUND); + newTransaction.setPaymentType(PaymentType.PAYPAL); + newTransaction.getTransactionDetails().put("TRANSACTIONID", refundTransactionResponse.getRefundTransactionID()); + transaction.getTransactionDetails().put("CORRELATION", refundTransactionResponse.getCorrelationID()); + + + + return newTransaction; + + + } catch(Exception e) { + if(e instanceof IntegrationException) { + throw (IntegrationException)e; + } else { + throw new IntegrationException(e); + } + } + + + + + + + } + + private Transaction processTransaction(MerchantStore store, + Customer customer, List items, BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + + com.salesmanager.core.model.payments.PaypalPayment paypalPayment = (com.salesmanager.core.model.payments.PaypalPayment)payment; + + try { + + + String mode = "sandbox"; + String env = configuration.getEnvironment(); + if(Constants.PRODUCTION_ENVIRONMENT.equals(env)) { + mode = "production"; + } + + + //get token from url and return the user to generate a payerid + + GetExpressCheckoutDetailsRequestType getExpressCheckoutDetailsRequest = new GetExpressCheckoutDetailsRequestType(paypalPayment.getPaymentToken()); + getExpressCheckoutDetailsRequest.setVersion("104.0"); + + GetExpressCheckoutDetailsReq getExpressCheckoutDetailsReq = new GetExpressCheckoutDetailsReq(); + getExpressCheckoutDetailsReq.setGetExpressCheckoutDetailsRequest(getExpressCheckoutDetailsRequest); + + Map configurationMap = new HashMap(); + configurationMap.put("mode", mode); + configurationMap.put("acct1.UserName", configuration.getIntegrationKeys().get("username")); + configurationMap.put("acct1.Password", configuration.getIntegrationKeys().get("api")); + configurationMap.put("acct1.Signature", configuration.getIntegrationKeys().get("signature")); + + + PayPalAPIInterfaceServiceService service = new PayPalAPIInterfaceServiceService(configurationMap); + GetExpressCheckoutDetailsResponseType getExpressCheckoutDetailsResponse = service.getExpressCheckoutDetails(getExpressCheckoutDetailsReq); + + + String token = getExpressCheckoutDetailsResponse.getGetExpressCheckoutDetailsResponseDetails().getToken(); + String correlationID = getExpressCheckoutDetailsResponse.getCorrelationID(); + String ack = getExpressCheckoutDetailsResponse.getAck().getValue(); + String payerId = getExpressCheckoutDetailsResponse.getGetExpressCheckoutDetailsResponseDetails().getPayerInfo().getPayerID(); + + //TOKEN=EC-9VT64354BS889423P&CHECKOUTSTATUS=PaymentActionNotInitiated&TIMESTAMP=2014-01-26T17:30:17Z&CORRELATIONID=84dfe1d0939cc&ACK=Success&VERSION=104.0&BUILD=9285531&EMAIL=csamson777-facilitator@yahoo.com&PAYERID=XURV79Z6URDV4&PAYERSTATUS=verified&BUSINESS=facilitator account's Test Store&FIRSTNAME=facilitator&LASTNAME=account&COUNTRYCODE=US&SHIPTONAME=facilitator account's Test Store&SHIPTOSTREET=1 Main St&SHIPTOCITY=San Jose&SHIPTOSTATE=CA&SHIPTOZIP=95131&SHIPTOCOUNTRYCODE=US&SHIPTOCOUNTRYNAME=United States&ADDRESSSTATUS=Confirmed&CURRENCYCODE=USD&AMT=1.00&ITEMAMT=1.00&SHIPPINGAMT=0.00&HANDLINGAMT=0.00&TAXAMT=0.00&INSURANCEAMT=0.00&SHIPDISCAMT=0.00&L_NAME0=item&L_QTY0=1&L_TAXAMT0=0.00&L_AMT0=1.00&L_ITEMWEIGHTVALUE0= 0.00000&L_ITEMLENGTHVALUE0= 0.00000&L_ITEMWIDTHVALUE0= 0.00000&L_ITEMHEIGHTVALUE0= 0.00000&PAYMENTREQUEST_0_CURRENCYCODE=USD&PAYMENTREQUEST_0_AMT=1.00&PAYMENTREQUEST_0_ITEMAMT=1.00&PAYMENTREQUEST_0_SHIPPINGAMT=0.00&PAYMENTREQUEST_0_HANDLINGAMT=0.00&PAYMENTREQUEST_0_TAXAMT=0.00&PAYMENTREQUEST_0_INSURANCEAMT=0.00&PAYMENTREQUEST_0_SHIPDISCAMT=0.00&PAYMENTREQUEST_0_INSURANCEOPTIONOFFERED=false&PAYMENTREQUEST_0_SHIPTONAME=facilitator account's Test Store&PAYMENTREQUEST_0_SHIPTOSTREET=1 Main St&PAYMENTREQUEST_0_SHIPTOCITY=San Jose&PAYMENTREQUEST_0_SHIPTOSTATE=CA&PAYMENTREQUEST_0_SHIPTOZIP=95131&PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE=US&PAYMENTREQUEST_0_SHIPTOCOUNTRYNAME=United States&PAYMENTREQUEST_0_ADDRESSSTATUS=Confirmed&PAYMENTREQUEST_0_ADDRESSNORMALIZATIONSTATUS=None&L_PAYMENTREQUEST_0_NAME0=item&L_PAYMENTREQUEST_0_QTY0=1&L_PAYMENTREQUEST_0_TAXAMT0=0.00&L_PAYMENTREQUEST_0_AMT0=1.00&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE0= 0.00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE0= 0.00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE0= 0.00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE0= 0.00000&PAYMENTREQUESTINFO_0_ERRORCODE=0 + + if(!"Success".equals(ack)) { + LOGGER.error("Wrong value from anthorize and capture transaction " + ack); + throw new IntegrationException("Wrong paypal ack from init transaction " + ack); + } + + + PaymentDetailsType paymentDetail = new PaymentDetailsType(); + /** IPN **/ + //paymentDetail.setNotifyURL("http://replaceIpnUrl.com"); + BasicAmountType orderTotal = new BasicAmountType(); + orderTotal.setValue(pricingService.getStringAmount(amount, store)); + orderTotal.setCurrencyID(urn.ebay.apis.eBLBaseComponents.CurrencyCodeType.fromValue(payment.getCurrency().getCode())); + paymentDetail.setOrderTotal(orderTotal); + paymentDetail.setButtonSource("Shopizer_Cart_AP"); + /** sale or pre-auth **/ + if(payment.getTransactionType().name().equals(TransactionType.AUTHORIZE.name())) { + paymentDetail.setPaymentAction(urn.ebay.apis.eBLBaseComponents.PaymentActionCodeType.AUTHORIZATION); + } else { + paymentDetail.setPaymentAction(urn.ebay.apis.eBLBaseComponents.PaymentActionCodeType.SALE); + } + + List paymentDetails = new ArrayList(); + paymentDetails.add(paymentDetail); + + DoExpressCheckoutPaymentRequestDetailsType doExpressCheckoutPaymentRequestDetails = new DoExpressCheckoutPaymentRequestDetailsType(); + doExpressCheckoutPaymentRequestDetails.setToken(token); + doExpressCheckoutPaymentRequestDetails.setPayerID(payerId); + doExpressCheckoutPaymentRequestDetails.setPaymentDetails(paymentDetails); + + DoExpressCheckoutPaymentRequestType doExpressCheckoutPaymentRequest = new DoExpressCheckoutPaymentRequestType(doExpressCheckoutPaymentRequestDetails); + doExpressCheckoutPaymentRequest.setVersion("104.0"); + + DoExpressCheckoutPaymentReq doExpressCheckoutPaymentReq = new DoExpressCheckoutPaymentReq(); + doExpressCheckoutPaymentReq.setDoExpressCheckoutPaymentRequest(doExpressCheckoutPaymentRequest); + + + DoExpressCheckoutPaymentResponseType doExpressCheckoutPaymentResponse = service.doExpressCheckoutPayment(doExpressCheckoutPaymentReq); + String commitAck = doExpressCheckoutPaymentResponse.getAck().getValue(); + + + if(!"Success".equals(commitAck)) { + LOGGER.error("Wrong value from transaction commit " + ack); + throw new IntegrationException("Wrong paypal ack from init transaction " + ack); + } + + + List paymentInfoList = doExpressCheckoutPaymentResponse.getDoExpressCheckoutPaymentResponseDetails().getPaymentInfo(); + String transactionId = null; + + for(PaymentInfoType paymentInfo : paymentInfoList) { + transactionId = paymentInfo.getTransactionID(); + } + + + + + //TOKEN=EC-90U93956LU4997256&SUCCESSPAGEREDIRECTREQUESTED=false&TIMESTAMP=2014-02-16T15:41:03Z&CORRELATIONID=39d4ab666c1d7&ACK=Success&VERSION=104.0&BUILD=9720069&INSURANCEOPTIONSELECTED=false&SHIPPINGOPTIONISDEFAULT=false&PAYMENTINFO_0_TRANSACTIONID=4YA742984J1256935&PAYMENTINFO_0_TRANSACTIONTYPE=expresscheckout&PAYMENTINFO_0_PAYMENTTYPE=instant&PAYMENTINFO_0_ORDERTIME=2014-02-16T15:41:03Z&PAYMENTINFO_0_AMT=1.00&PAYMENTINFO_0_FEEAMT=0.33&PAYMENTINFO_0_TAXAMT=0.00&PAYMENTINFO_0_CURRENCYCODE=USD&PAYMENTINFO_0_PAYMENTSTATUS=Completed&PAYMENTINFO_0_PENDINGREASON=None&PAYMENTINFO_0_REASONCODE=None&PAYMENTINFO_0_PROTECTIONELIGIBILITY=Eligible&PAYMENTINFO_0_PROTECTIONELIGIBILITYTYPE=ItemNotReceivedEligible,UnauthorizedPaymentEligible&PAYMENTINFO_0_SECUREMERCHANTACCOUNTID=TWLK53YN7GDM6&PAYMENTINFO_0_ERRORCODE=0&PAYMENTINFO_0_ACK=Success + + Transaction transaction = new Transaction(); + transaction.setAmount(amount); + transaction.setTransactionDate(new Date()); + transaction.setTransactionType(payment.getTransactionType()); + transaction.setPaymentType(PaymentType.PAYPAL); + transaction.getTransactionDetails().put("TOKEN", token); + transaction.getTransactionDetails().put("PAYERID", payerId); + transaction.getTransactionDetails().put("TRANSACTIONID", transactionId); + transaction.getTransactionDetails().put("CORRELATION", correlationID); + + + + return transaction; + + + } catch(Exception e) { + throw new IntegrationException(e); + } + + + + } + + @Override + public Transaction capture(MerchantStore store, Customer customer, + Order order, Transaction capturableTransaction, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + + + try { + + + + Validate.notNull(capturableTransaction,"Transaction cannot be null"); + Validate.notNull(capturableTransaction.getTransactionDetails().get("TRANSACTIONID"), "Transaction details must contain a TRANSACTIONID"); + Validate.notNull(order,"Order must not be null"); + Validate.notNull(order.getCurrency(),"Order nust contain Currency object"); + + String mode = "sandbox"; + String env = configuration.getEnvironment(); + if(Constants.PRODUCTION_ENVIRONMENT.equals(env)) { + mode = "production"; + } + + + Map configurationMap = new HashMap(); + configurationMap.put("mode", mode); + configurationMap.put("acct1.UserName", configuration.getIntegrationKeys().get("username")); + configurationMap.put("acct1.Password", configuration.getIntegrationKeys().get("api")); + configurationMap.put("acct1.Signature", configuration.getIntegrationKeys().get("signature")); + + + DoCaptureReq doCaptureReq = new DoCaptureReq(); + + + + + BasicAmountType amount = new BasicAmountType(); + amount.setValue(pricingService.getStringAmount(order.getTotal(), store)); + amount.setCurrencyID(urn.ebay.apis.eBLBaseComponents.CurrencyCodeType.fromValue(order.getCurrency().getCode())); + + // DoCaptureRequest which takes mandatory params: + // + // Authorization ID - Authorization identification number of the + // payment you want to capture. This is the transaction ID + DoCaptureRequestType doCaptureRequest = new DoCaptureRequestType( + capturableTransaction.getTransactionDetails().get("TRANSACTIONID"), amount, CompleteCodeType.NOTCOMPLETE); + + doCaptureReq.setDoCaptureRequest(doCaptureRequest); + + // ## Creating service wrapper object + // Creating service wrapper object to make API call and loading + // configuration file for your credentials and endpoint + PayPalAPIInterfaceServiceService service = new PayPalAPIInterfaceServiceService(configurationMap); + + DoCaptureResponseType doCaptureResponse = null; + + // ## Making API call + // Invoke the appropriate method corresponding to API in service + // wrapper object + doCaptureResponse = service + .doCapture(doCaptureReq); + + + // ## Accessing response parameters + // You can access the response parameters using getter methods in + // response object as shown below + // ### Success values + if(!"Success".equals(doCaptureResponse.getAck().getValue())) { + LOGGER.error("Wrong value from transaction commit " + doCaptureResponse.getAck().getValue()); + throw new IntegrationException("Wrong paypal ack from refund transaction " + doCaptureResponse.getAck().getValue()); + } + //if (doCaptureResponse.getAck().getValue() + // .equalsIgnoreCase("success")) { + + // Authorization identification number + //logger.info("Authorization ID:" + // + doCaptureResponse.getDoCaptureResponseDetails() + // .getAuthorizationID()); + //} + // ### Error Values + // Access error values from error list using getter methods + //else { + // List errorList = doCaptureResponse.getErrors(); + // logger.severe("API Error Message : " + // + errorList.get(0).getLongMessage()); + //} + + //String refundAck = refundTransactionResponse.getAck().getValue(); + + + + + + Transaction newTransaction = new Transaction(); + newTransaction.setAmount(order.getTotal()); + newTransaction.setTransactionDate(new Date()); + newTransaction.setTransactionType(TransactionType.CAPTURE); + newTransaction.setPaymentType(PaymentType.PAYPAL); + newTransaction.getTransactionDetails().put("AUTHORIZATIONID", doCaptureResponse.getDoCaptureResponseDetails().getAuthorizationID()); + newTransaction.getTransactionDetails().put("TRANSACTIONID", capturableTransaction.getTransactionDetails().get("TRANSACTIONID")); + + return newTransaction; + + + } catch(Exception e) { + throw new IntegrationException(e); + } + + + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/PayPalRestPayment.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/PayPalRestPayment.java new file mode 100755 index 0000000000..7df212b63f --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/PayPalRestPayment.java @@ -0,0 +1,251 @@ +package com.salesmanager.core.business.modules.integration.payment.impl; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; + +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.payments.Payment; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +//import com.paypal.core.rest.OAuthTokenCredential; +//import com.paypal.core.rest.PayPalRESTException; +import com.salesmanager.core.modules.integration.IntegrationException; +import com.salesmanager.core.modules.integration.payment.model.PaymentModule; + + +public class PayPalRestPayment implements PaymentModule { + + + @Override + public void validateModuleConfiguration( + IntegrationConfiguration integrationConfiguration, + MerchantStore store) throws IntegrationException { + + + List errorFields = null; + + //validate integrationKeys['account'] + Map keys = integrationConfiguration.getIntegrationKeys(); + if(keys==null || StringUtils.isBlank(keys.get("client"))) { + errorFields = new ArrayList(); + errorFields.add("client"); + } + + if(keys==null || StringUtils.isBlank(keys.get("secret"))) { + if(errorFields==null) { + errorFields = new ArrayList(); + } + errorFields.add("secret"); + } + + + if(errorFields!=null) { + IntegrationException ex = new IntegrationException(IntegrationException.ERROR_VALIDATION_SAVE); + ex.setErrorFields(errorFields); + throw ex; + + } + + } + + @Override + public Transaction initTransaction(MerchantStore store, Customer customer, + BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + // TODO Auto-generated method stub + return null; + } + + @Override + public Transaction authorize(MerchantStore store, Customer customer, + List items, BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + return null; + +/* + // ###AccessToken + // Retrieve the access token from + // OAuthTokenCredential by passing in + // ClientID and ClientSecret + APIContext apiContext = null; + String accessToken = null; + + try { + + String clientID = configuration.getIntegrationKeys().get("client"); + String secret = configuration.getIntegrationKeys().get("secret"); + + accessToken = getAccessToken(clientID, secret); + + // ### Api Context + // Pass in a `ApiContext` object to authenticate + // the call and to send a unique request id + // (that ensures idempotency). The SDK generates + // a request id if you do not pass one explicitly. + apiContext = new APIContext(accessToken); + // Use this variant if you want to pass in a request id + // that is meaningful in your application, ideally + // a order id. + + * String requestId = Long.toString(System.nanoTime(); APIContext + * apiContext = new APIContext(accessToken, requestId )); + + + // ###Authorization + // Retrieve an Authorization Id + // by making a Payment with intent + // as 'authorize' and parsing through + // the Payment object + + + String authorizationID = null; + + // ###Details + // Let's you specify details of a payment amount. + //Details details = new Details(); + //details.setShipping("0.03"); + //details.setSubtotal("107.41"); + //details.setTax("0.03"); + + // ###Amount + // Let's you specify a payment amount. + + String sAmount = productPriceUtils.getAdminFormatedAmount(store, amount); + + + Amount amnt = new Amount(); + amnt.setCurrency(store.getCurrency().getCode()); + amnt.setTotal(sAmount); + //amnt.setDetails(details); + + // ###Transaction + // A transaction defines the contract of a + // payment - what is the payment for and who + // is fulfilling it. Transaction is created with + // a `Payee` and `Amount` types + com.paypal.api.payments.Transaction transaction = new com.paypal.api.payments.Transaction(); + transaction.setAmount(amnt); + //TODO change description + transaction.setDescription("This is the payment transaction description."); + + // The Payment creation API requires a list of + // Transaction; add the created `Transaction` + // to a List + List transactions = new ArrayList(); + transactions.add(transaction); + + // ###Payer + // A resource representing a Payer that funds a payment + // Payment Method + // as 'paypal' + Payer payer = new Payer(); + payer.setPaymentMethod("paypal"); + + // ###Payment + // A Payment Resource; create one using + // the above types and intent as 'sale' + com.paypal.api.payments.Payment ppayment = new com.paypal.api.payments.Payment(); + ppayment.setIntent("sale"); + ppayment.setPayer(payer); + ppayment.setTransactions(transactions); + + // ###Redirect URLs + RedirectUrls redirectUrls = new RedirectUrls(); + String guid = UUID.randomUUID().toString().replaceAll("-", ""); + redirectUrls.setCancelUrl(req.getScheme() + "://" + + req.getServerName() + ":" + req.getServerPort() + + req.getContextPath() + "/paymentwithpaypal?guid=" + guid); + redirectUrls.setReturnUrl(req.getScheme() + "://" + + req.getServerName() + ":" + req.getServerPort() + + req.getContextPath() + "/paymentwithpaypal?guid=" + guid); + payment.setRedirectUrls(redirectUrls); + + // Create a payment by posting to the APIService + // using a valid AccessToken + // The return object contains the status; + try { + Payment createdPayment = payment.create(apiContext); + LOGGER.info("Created payment with id = " + + createdPayment.getId() + " and status = " + + createdPayment.getState()); + // ###Payment Approval Url + Iterator links = createdPayment.getLinks().iterator(); + while (links.hasNext()) { + Links link = links.next(); + if (link.getRel().equalsIgnoreCase("approval_url")) { + req.setAttribute("redirectURL", link.getHref()); + } + } + req.setAttribute("response", Payment.getLastResponse()); + map.put(guid, createdPayment.getId()); + } catch (PayPalRESTException e) { + req.setAttribute("error", e.getMessage()); + } + } catch (PayPalRESTException e) { + throw new IntegrationException(e); + } +*/ + + + } + +/* @Override + public Transaction capture(MerchantStore store, Customer customer, + List items, BigDecimal amount, Payment payment, Transaction transaction, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + // TODO Auto-generated method stub + return null; + }*/ + + @Override + public Transaction authorizeAndCapture(MerchantStore store, + Customer customer, List items, BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + // TODO Auto-generated method stub + return null; + } + + @Override + public Transaction refund(boolean partial, MerchantStore store, + Transaction transaction, Order order, BigDecimal amount, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + // TODO Auto-generated method stub + return null; + } + + private String getAccessToken(String clientID, String clientSecret) throws Exception { + + // ###AccessToken + // Retrieve the access token from + // OAuthTokenCredential by passing in + // ClientID and ClientSecret + + return null; + //return new OAuthTokenCredential(clientID, clientSecret) + // .getAccessToken(); + } + + @Override + public Transaction capture(MerchantStore store, Customer customer, + Order order, Transaction capturableTransaction, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/Stripe3Payment.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/Stripe3Payment.java new file mode 100755 index 0000000000..b9bf4f6e60 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/Stripe3Payment.java @@ -0,0 +1,621 @@ +package com.salesmanager.core.business.modules.integration.payment.impl; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.salesmanager.core.business.utils.ProductPriceUtils; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.payments.Payment; +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.payments.TransactionType; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.modules.integration.IntegrationException; +import com.salesmanager.core.modules.integration.payment.model.PaymentModule; +import com.stripe.Stripe; +import com.stripe.exception.AuthenticationException; +import com.stripe.exception.CardException; +import com.stripe.exception.InvalidRequestException; +import com.stripe.exception.StripeException; +import com.stripe.model.PaymentIntent; +import com.stripe.model.Refund; +import com.stripe.param.PaymentIntentCaptureParams; +import com.stripe.param.PaymentIntentCreateParams; + +// import com.stripe.exception.APIConnectionException; + +public class Stripe3Payment implements PaymentModule { + + private static final Logger LOGGER = LoggerFactory.getLogger(Stripe3Payment.class); + + @Inject + private ProductPriceUtils productPriceUtils; + + private final static String AUTHORIZATION = "Authorization"; + private final static String TRANSACTION = "Transaction"; + + + @Override + public Transaction initTransaction(MerchantStore store, Customer customer, + BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + + String strAmount = String.valueOf(amount); + strAmount = strAmount.replace(".",""); + + Transaction transaction = new Transaction(); + try { + + + String apiKey = configuration.getIntegrationKeys().get("secretKey"); + + if (StringUtils.isBlank(apiKey)) { + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing payment.metaData"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + Stripe.apiKey = apiKey; + + PaymentIntentCreateParams createParams = new PaymentIntentCreateParams.Builder() + .setCurrency(store.getCurrency().getCode()) + .setAmount(Long.parseLong(strAmount)) + .setCaptureMethod(PaymentIntentCreateParams.CaptureMethod.MANUAL) + .build(); + + // Create a PaymentIntent with the order amount and currency + PaymentIntent intent = PaymentIntent.create(createParams); + + intent.getClientSecret(); + + transaction.setAmount(amount); + //transaction.setOrder(order); + transaction.setTransactionDate(new Date()); + transaction.setTransactionType(TransactionType.AUTHORIZE); + transaction.setPaymentType(PaymentType.CREDITCARD); + transaction.getTransactionDetails().put("TRANSACTIONID", intent.getId()); + transaction.getTransactionDetails().put("TRNAPPROVED", intent.getStatus()); + transaction.getTransactionDetails().put("TRNORDERNUMBER", intent.getId()); + transaction.getTransactionDetails().put("INTENTSECRET", intent.getClientSecret()); + transaction.getTransactionDetails().put("MESSAGETEXT", null); + + } catch (Exception e) { + throw buildException(e); + } + + return transaction; + } + + @Override + public void validateModuleConfiguration( + IntegrationConfiguration integrationConfiguration, + MerchantStore store) throws IntegrationException { + + + List errorFields = null; + + + Map keys = integrationConfiguration.getIntegrationKeys(); + + //validate integrationKeys['secretKey'] + if(keys==null || StringUtils.isBlank(keys.get("secretKey"))) { + errorFields = new ArrayList(); + errorFields.add("secretKey"); + } + + //validate integrationKeys['publishableKey'] + if(keys==null || StringUtils.isBlank(keys.get("publishableKey"))) { + if(errorFields==null) { + errorFields = new ArrayList(); + } + errorFields.add("publishableKey"); + } + + + if(errorFields!=null) { + IntegrationException ex = new IntegrationException(IntegrationException.ERROR_VALIDATION_SAVE); + ex.setErrorFields(errorFields); + throw ex; + } + } + + + /* ----------------------------------------- */ + + @Override + public Transaction authorize(MerchantStore store, Customer customer, + List items, BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + Transaction transaction = new Transaction(); + try { + + + String apiKey = configuration.getIntegrationKeys().get("secretKey"); + + if(payment.getPaymentMetaData()==null || StringUtils.isBlank(apiKey)) { + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing payment.metaData"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + /** + * This is the PaymentIntent ID created on the Frontend, that we will now store. + */ + String token = payment.getPaymentMetaData().get("stripe_token"); + + if(StringUtils.isBlank(token)) { + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing stripe token"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + Stripe.apiKey = apiKey; + + PaymentIntent paymentIntent = PaymentIntent.retrieve( + token + ); + + transaction.setAmount(amount); + //transaction.setOrder(order); + transaction.setTransactionDate(new Date()); + transaction.setTransactionType(TransactionType.AUTHORIZE); + transaction.setPaymentType(PaymentType.CREDITCARD); + transaction.getTransactionDetails().put("TRANSACTIONID", token); + transaction.getTransactionDetails().put("TRNAPPROVED", paymentIntent.getStatus()); + transaction.getTransactionDetails().put("TRNORDERNUMBER", paymentIntent.getId()); // <---- We store the PI id here + transaction.getTransactionDetails().put("MESSAGETEXT", null); + + } catch (Exception e) { + + throw buildException(e); + + } + + return transaction; + + + } + + @Override + public Transaction capture(MerchantStore store, Customer customer, + Order order, Transaction capturableTransaction, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + Transaction transaction = new Transaction(); + try { + + String apiKey = configuration.getIntegrationKeys().get("secretKey"); + + if(StringUtils.isBlank(apiKey)) { + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing payment.metaData"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + String chargeId = capturableTransaction.getTransactionDetails().get("TRNORDERNUMBER"); // <---- We retrieve the PI id here + + if(StringUtils.isBlank(chargeId)) { + IntegrationException te = new IntegrationException( + "Can't process Stripe capture, missing TRNORDERNUMBER"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + String amnt = productPriceUtils.getAdminFormatedAmount(store, order.getTotal()); + String strAmount = String.valueOf(amnt); + strAmount = strAmount.replace(".",""); + + Stripe.apiKey = apiKey; + + + PaymentIntent paymentIntent = PaymentIntent.retrieve( + chargeId + ); + + PaymentIntentCaptureParams params = + PaymentIntentCaptureParams.builder() + .setAmountToCapture(Long.parseLong(strAmount)) + .setStatementDescriptor( + store.getStorename().length() > 22 ? + store.getStorename().substring(0, 22) : + store.getStorename() + ) + .build(); + + paymentIntent = paymentIntent.capture(params); + + transaction.setAmount(order.getTotal()); + transaction.setOrder(order); + transaction.setTransactionDate(new Date()); + transaction.setTransactionType(TransactionType.CAPTURE); + transaction.setPaymentType(PaymentType.CREDITCARD); + transaction.getTransactionDetails().put("TRANSACTIONID", capturableTransaction.getTransactionDetails().get("TRANSACTIONID")); + transaction.getTransactionDetails().put("TRNAPPROVED", paymentIntent.getStatus()); + transaction.getTransactionDetails().put("TRNORDERNUMBER", paymentIntent.getId()); + transaction.getTransactionDetails().put("MESSAGETEXT", null); + + return transaction; + + } catch (Exception e) { + throw buildException(e); + } + } + + @Override + public Transaction authorizeAndCapture(MerchantStore store, Customer customer, + List items, BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + String apiKey = configuration.getIntegrationKeys().get("secretKey"); + + if(payment.getPaymentMetaData()==null || StringUtils.isBlank(apiKey)) { + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing payment.metaData"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + String token = payment.getPaymentMetaData().get("stripe_token"); + if(StringUtils.isBlank(token)) { //possibly from api + token = payment.getPaymentMetaData().get("paymentToken"); + } + + if(StringUtils.isBlank(token)) { + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing stripe token"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + + + Transaction transaction = new Transaction(); + try { + + String amnt = productPriceUtils.getAdminFormatedAmount(store, amount); + + //stripe does not support floating point + //so amnt * 100 or remove floating point + //553.47 = 55347 + + + String strAmount = String.valueOf(amnt); + strAmount = strAmount.replace(".",""); + + /*Map chargeParams = new HashMap(); + chargeParams.put("amount", strAmount); + chargeParams.put("capture", true); + chargeParams.put("currency", store.getCurrency().getCode()); + chargeParams.put("source", token); // obtained with Stripe.js + chargeParams.put("description", new StringBuilder().append(TRANSACTION).append(" - ").append(store.getStorename()).toString()); + */ + + Stripe.apiKey = apiKey; + + + PaymentIntent paymentIntent = PaymentIntent.retrieve( + token + ); + + PaymentIntentCaptureParams params = + PaymentIntentCaptureParams.builder() + .setAmountToCapture(Long.parseLong(strAmount)) + .setStatementDescriptor( + store.getStorename().length() > 22 ? + store.getStorename().substring(0, 22) : + store.getStorename() + ) + .build(); + + paymentIntent = paymentIntent.capture(params); + + //Map metadata = ch.getMetadata(); + + + transaction.setAmount(amount); + //transaction.setOrder(order); + transaction.setTransactionDate(new Date()); + transaction.setTransactionType(TransactionType.AUTHORIZECAPTURE); + transaction.setPaymentType(PaymentType.CREDITCARD); + transaction.getTransactionDetails().put("TRANSACTIONID", token); + transaction.getTransactionDetails().put("TRNAPPROVED", paymentIntent.getStatus()); + transaction.getTransactionDetails().put("TRNORDERNUMBER", paymentIntent.getId()); + transaction.getTransactionDetails().put("MESSAGETEXT", null); + + } catch (Exception e) { + + e.printStackTrace(); + + throw buildException(e); + + } + + return transaction; + + } + + @Override + public Transaction refund(boolean partial, MerchantStore store, Transaction transaction, + Order order, BigDecimal amount, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + + + String apiKey = configuration.getIntegrationKeys().get("secretKey"); + + if(StringUtils.isBlank(apiKey)) { + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing payment.metaData"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + try { + + + String trnID = transaction.getTransactionDetails().get("TRNORDERNUMBER"); + + String amnt = productPriceUtils.getAdminFormatedAmount(store, amount); + + Stripe.apiKey = apiKey; + + //stripe does not support floating point + //so amnt * 100 or remove floating point + //553.47 = 55347 + + String strAmount = String.valueOf(amnt); + strAmount = strAmount.replace(".",""); + + PaymentIntent paymentIntent = PaymentIntent.retrieve( + trnID + ); + + Map params = new HashMap<>(); + params.put("payment_intent", paymentIntent.getId()); + params.put("amount", strAmount); + Refund re = Refund.create(params); + + transaction = new Transaction(); + transaction.setAmount(order.getTotal()); + transaction.setOrder(order); + transaction.setTransactionDate(new Date()); + transaction.setTransactionType(TransactionType.CAPTURE); + transaction.setPaymentType(PaymentType.CREDITCARD); + transaction.getTransactionDetails().put("TRANSACTIONID", transaction.getTransactionDetails().get("TRANSACTIONID")); + transaction.getTransactionDetails().put("TRNAPPROVED", re.getReason()); + transaction.getTransactionDetails().put("TRNORDERNUMBER", re.getId()); + transaction.getTransactionDetails().put("MESSAGETEXT", null); + + return transaction; + + + } catch(Exception e) { + + throw buildException(e); + + } + + + + } + + private IntegrationException buildException(Exception ex) { + + + if(ex instanceof CardException) { + CardException e = (CardException)ex; + // Since it's a decline, CardException will be caught + //System.out.println("Status is: " + e.getCode()); + //System.out.println("Message is: " + e.getMessage()); + + + /** + * + invalid_number The card number is not a valid credit card number. + invalid_expiry_month The card's expiration month is invalid. + invalid_expiry_year The card's expiration year is invalid. + invalid_cvc The card's security code is invalid. + incorrect_number The card number is incorrect. + expired_card The card has expired. + incorrect_cvc The card's security code is incorrect. + incorrect_zip The card's zip code failed validation. + card_declined The card was declined. + missing There is no card on a customer that is being charged. + processing_error An error occurred while processing the card. + rate_limit An error occurred due to requests hitting the API too quickly. Please let us know if you're consistently running into this error. + */ + + + String declineCode = e.getDeclineCode(); + + if("card_declined".equals(declineCode)) { + IntegrationException te = new IntegrationException( + "Can't process stripe message " + e.getMessage()); + te.setExceptionType(IntegrationException.EXCEPTION_PAYMENT_DECLINED); + te.setMessageCode("message.payment.declined"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + return te; + } + + if("invalid_number".equals(declineCode)) { + IntegrationException te = new IntegrationException( + "Can't process stripe message " + e.getMessage()); + te.setExceptionType(IntegrationException.EXCEPTION_VALIDATION); + te.setMessageCode("messages.error.creditcard.number"); + te.setErrorCode(IntegrationException.EXCEPTION_VALIDATION); + return te; + } + + if("invalid_expiry_month".equals(declineCode)) { + IntegrationException te = new IntegrationException( + "Can't process stripe message " + e.getMessage()); + te.setExceptionType(IntegrationException.EXCEPTION_VALIDATION); + te.setMessageCode("messages.error.creditcard.dateformat"); + te.setErrorCode(IntegrationException.EXCEPTION_VALIDATION); + return te; + } + + if("invalid_expiry_year".equals(declineCode)) { + IntegrationException te = new IntegrationException( + "Can't process stripe message " + e.getMessage()); + te.setExceptionType(IntegrationException.EXCEPTION_VALIDATION); + te.setMessageCode("messages.error.creditcard.dateformat"); + te.setErrorCode(IntegrationException.EXCEPTION_VALIDATION); + return te; + } + + if("invalid_cvc".equals(declineCode)) { + IntegrationException te = new IntegrationException( + "Can't process stripe message " + e.getMessage()); + te.setExceptionType(IntegrationException.EXCEPTION_VALIDATION); + te.setMessageCode("messages.error.creditcard.cvc"); + te.setErrorCode(IntegrationException.EXCEPTION_VALIDATION); + return te; + } + + if("incorrect_number".equals(declineCode)) { + IntegrationException te = new IntegrationException( + "Can't process stripe message " + e.getMessage()); + te.setExceptionType(IntegrationException.EXCEPTION_VALIDATION); + te.setMessageCode("messages.error.creditcard.number"); + te.setErrorCode(IntegrationException.EXCEPTION_VALIDATION); + return te; + } + + if("incorrect_cvc".equals(declineCode)) { + IntegrationException te = new IntegrationException( + "Can't process stripe message " + e.getMessage()); + te.setExceptionType(IntegrationException.EXCEPTION_VALIDATION); + te.setMessageCode("messages.error.creditcard.cvc"); + te.setErrorCode(IntegrationException.EXCEPTION_VALIDATION); + return te; + } + + //nothing good so create generic error + IntegrationException te = new IntegrationException( + "Can't process stripe card " + e.getMessage()); + te.setExceptionType(IntegrationException.EXCEPTION_VALIDATION); + te.setMessageCode("messages.error.creditcard.number"); + te.setErrorCode(IntegrationException.EXCEPTION_VALIDATION); + return te; + + + + } else if (ex instanceof InvalidRequestException) { + LOGGER.error("InvalidRequest error with stripe", ex.getMessage()); + InvalidRequestException e =(InvalidRequestException)ex; + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing invalid payment parameters"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("messages.error.creditcard.number"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + return te; + + } else if (ex instanceof AuthenticationException) { + LOGGER.error("Authentication error with stripe", ex.getMessage()); + AuthenticationException e = (AuthenticationException)ex; + // Authentication with Stripe's API failed + // (maybe you changed API keys recently) + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing invalid payment parameters"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + return te; + + } /*else if (ex instanceof APIConnectionException) { + LOGGER.error("API connection error with stripe", ex.getMessage()); + APIConnectionException e = (APIConnectionException)ex; + // Network communication with Stripe failed + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing invalid payment parameters"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + return te; + } */else if (ex instanceof StripeException) { + LOGGER.error("Error with stripe", ex.getMessage()); + StripeException e = (StripeException)ex; + // Display a very generic error to the user, and maybe send + // yourself an email + IntegrationException te = new IntegrationException( + "Can't process Stripe authorize, missing invalid payment parameters"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + return te; + + + + } else if (ex instanceof Exception) { + LOGGER.error("Stripe module error", ex.getMessage()); + if(ex instanceof IntegrationException) { + return (IntegrationException)ex; + } else { + IntegrationException te = new IntegrationException( + "Can't process Stripe authorize, exception", ex); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + return te; + } + + + } else { + LOGGER.error("Stripe module error", ex.getMessage()); + IntegrationException te = new IntegrationException( + "Can't process Stripe authorize, exception", ex); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + return te; + } + + } + + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/StripePayment.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/StripePayment.java new file mode 100755 index 0000000000..eacc34ceb4 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/payment/impl/StripePayment.java @@ -0,0 +1,576 @@ +package com.salesmanager.core.business.modules.integration.payment.impl; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.salesmanager.core.business.utils.ProductPriceUtils; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.payments.Payment; +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.payments.TransactionType; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.modules.integration.IntegrationException; +import com.salesmanager.core.modules.integration.payment.model.PaymentModule; +import com.stripe.Stripe; +// import com.stripe.exception.APIConnectionException; +import com.stripe.exception.AuthenticationException; +import com.stripe.exception.CardException; +import com.stripe.exception.InvalidRequestException; +import com.stripe.exception.StripeException; +import com.stripe.model.Charge; +import com.stripe.model.Refund; + +public class StripePayment implements PaymentModule { + + @Inject + private ProductPriceUtils productPriceUtils; + + + private final static String AUTHORIZATION = "Authorization"; + private final static String TRANSACTION = "Transaction"; + + private static final Logger LOGGER = LoggerFactory.getLogger(StripePayment.class); + + @Override + public void validateModuleConfiguration( + IntegrationConfiguration integrationConfiguration, + MerchantStore store) throws IntegrationException { + + + List errorFields = null; + + + Map keys = integrationConfiguration.getIntegrationKeys(); + + //validate integrationKeys['secretKey'] + if(keys==null || StringUtils.isBlank(keys.get("secretKey"))) { + errorFields = new ArrayList(); + errorFields.add("secretKey"); + } + + //validate integrationKeys['publishableKey'] + if(keys==null || StringUtils.isBlank(keys.get("publishableKey"))) { + if(errorFields==null) { + errorFields = new ArrayList(); + } + errorFields.add("publishableKey"); + } + + + if(errorFields!=null) { + IntegrationException ex = new IntegrationException(IntegrationException.ERROR_VALIDATION_SAVE); + ex.setErrorFields(errorFields); + throw ex; + + } + + + + } + + + @Override + public Transaction initTransaction(MerchantStore store, Customer customer, + BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + Validate.notNull(configuration,"Configuration cannot be null"); + String publicKey = configuration.getIntegrationKeys().get("publishableKey"); + Validate.notNull(publicKey,"Publishable key not found in configuration"); + + Transaction transaction = new Transaction(); + transaction.setAmount(amount); + transaction.setDetails(publicKey); + transaction.setPaymentType(payment.getPaymentType()); + transaction.setTransactionDate(new Date()); + transaction.setTransactionType(payment.getTransactionType()); + + return transaction; + } + + @Override + public Transaction authorize(MerchantStore store, Customer customer, + List items, BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + Transaction transaction = new Transaction(); + try { + + + String apiKey = configuration.getIntegrationKeys().get("secretKey"); + + if(payment.getPaymentMetaData()==null || StringUtils.isBlank(apiKey)) { + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing payment.metaData"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + /** + * this is send by stripe from tokenization ui + */ + String token = payment.getPaymentMetaData().get("stripe_token"); + + if(StringUtils.isBlank(token)) { + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing stripe token"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + + String amnt = productPriceUtils.getAdminFormatedAmount(store, amount); + + //stripe does not support floating point + //so amnt * 100 or remove floating point + //553.47 = 55347 + + String strAmount = String.valueOf(amnt); + strAmount = strAmount.replace(".",""); + + Map chargeParams = new HashMap(); + chargeParams.put("amount", strAmount); + chargeParams.put("capture", false); + chargeParams.put("currency", store.getCurrency().getCode()); + chargeParams.put("source", token); // obtained with Stripe.js + chargeParams.put("description", new StringBuilder().append(TRANSACTION).append(" - ").append(store.getStorename()).toString()); + + Stripe.apiKey = apiKey; + + + Charge ch = Charge.create(chargeParams); + + //Map metadata = ch.getMetadata(); + + + transaction.setAmount(amount); + //transaction.setOrder(order); + transaction.setTransactionDate(new Date()); + transaction.setTransactionType(TransactionType.AUTHORIZE); + transaction.setPaymentType(PaymentType.CREDITCARD); + transaction.getTransactionDetails().put("TRANSACTIONID", token); + transaction.getTransactionDetails().put("TRNAPPROVED", ch.getStatus()); + transaction.getTransactionDetails().put("TRNORDERNUMBER", ch.getId()); + transaction.getTransactionDetails().put("MESSAGETEXT", null); + + } catch (Exception e) { + + throw buildException(e); + + } + + return transaction; + + + } + + @Override + public Transaction capture(MerchantStore store, Customer customer, + Order order, Transaction capturableTransaction, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + + Transaction transaction = new Transaction(); + try { + + + String apiKey = configuration.getIntegrationKeys().get("secretKey"); + + if(StringUtils.isBlank(apiKey)) { + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing payment.metaData"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + String chargeId = capturableTransaction.getTransactionDetails().get("TRNORDERNUMBER"); + + if(StringUtils.isBlank(chargeId)) { + IntegrationException te = new IntegrationException( + "Can't process Stripe capture, missing TRNORDERNUMBER"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + + Stripe.apiKey = apiKey; + + Charge ch = Charge.retrieve(chargeId); + ch.capture(); + + + transaction.setAmount(order.getTotal()); + transaction.setOrder(order); + transaction.setTransactionDate(new Date()); + transaction.setTransactionType(TransactionType.CAPTURE); + transaction.setPaymentType(PaymentType.CREDITCARD); + transaction.getTransactionDetails().put("TRANSACTIONID", capturableTransaction.getTransactionDetails().get("TRANSACTIONID")); + transaction.getTransactionDetails().put("TRNAPPROVED", ch.getStatus()); + transaction.getTransactionDetails().put("TRNORDERNUMBER", ch.getId()); + transaction.getTransactionDetails().put("MESSAGETEXT", null); + + //authorize a preauth + + + return transaction; + + } catch (Exception e) { + + throw buildException(e); + + } + + } + + @Override + public Transaction authorizeAndCapture(MerchantStore store, Customer customer, + List items, BigDecimal amount, Payment payment, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + String apiKey = configuration.getIntegrationKeys().get("secretKey"); + + if(payment.getPaymentMetaData()==null || StringUtils.isBlank(apiKey)) { + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing payment.metaData"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + String token = payment.getPaymentMetaData().get("stripe_token"); + if(StringUtils.isBlank(token)) { //possibly from api + token = payment.getPaymentMetaData().get("paymentToken");//from api + } + + if(StringUtils.isBlank(token)) { + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing stripe token"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + + + Transaction transaction = new Transaction(); + try { + + String amnt = productPriceUtils.getAdminFormatedAmount(store, amount); + + //stripe does not support floating point + //so amnt * 100 or remove floating point + //553.47 = 55347 + + + String strAmount = String.valueOf(amnt); + strAmount = strAmount.replace(".",""); + + Map chargeParams = new HashMap(); + chargeParams.put("amount", strAmount); + chargeParams.put("capture", true); + chargeParams.put("currency", store.getCurrency().getCode()); + chargeParams.put("source", token); // obtained with Stripe.js + chargeParams.put("description", new StringBuilder().append(TRANSACTION).append(" - ").append(store.getStorename()).toString()); + + Stripe.apiKey = apiKey; + + + Charge ch = Charge.create(chargeParams); + + //Map metadata = ch.getMetadata(); + + + transaction.setAmount(amount); + //transaction.setOrder(order); + transaction.setTransactionDate(new Date()); + transaction.setTransactionType(TransactionType.AUTHORIZECAPTURE); + transaction.setPaymentType(PaymentType.CREDITCARD); + transaction.getTransactionDetails().put("TRANSACTIONID", token); + transaction.getTransactionDetails().put("TRNAPPROVED", ch.getStatus()); + transaction.getTransactionDetails().put("TRNORDERNUMBER", ch.getId()); + transaction.getTransactionDetails().put("MESSAGETEXT", null); + + } catch (Exception e) { + + throw buildException(e); + + } + + return transaction; + + } + + @Override + public Transaction refund(boolean partial, MerchantStore store, Transaction transaction, + Order order, BigDecimal amount, + IntegrationConfiguration configuration, IntegrationModule module) + throws IntegrationException { + + + + String apiKey = configuration.getIntegrationKeys().get("secretKey"); + + if(StringUtils.isBlank(apiKey)) { + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing payment.metaData"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + throw te; + } + + try { + + + String trnID = transaction.getTransactionDetails().get("TRNORDERNUMBER"); + + String amnt = productPriceUtils.getAdminFormatedAmount(store, amount); + + Stripe.apiKey = apiKey; + + //stripe does not support floating point + //so amnt * 100 or remove floating point + //553.47 = 55347 + + String strAmount = String.valueOf(amnt); + strAmount = strAmount.replace(".",""); + + Charge ch = Charge.retrieve(trnID); + + Map params = new HashMap<>(); + params.put("charge", ch.getId()); + params.put("amount", strAmount); + Refund re = Refund.create(params); + + transaction = new Transaction(); + transaction.setAmount(order.getTotal()); + transaction.setOrder(order); + transaction.setTransactionDate(new Date()); + transaction.setTransactionType(TransactionType.CAPTURE); + transaction.setPaymentType(PaymentType.CREDITCARD); + transaction.getTransactionDetails().put("TRANSACTIONID", transaction.getTransactionDetails().get("TRANSACTIONID")); + transaction.getTransactionDetails().put("TRNAPPROVED", re.getReason()); + transaction.getTransactionDetails().put("TRNORDERNUMBER", re.getId()); + transaction.getTransactionDetails().put("MESSAGETEXT", null); + + return transaction; + + + } catch(Exception e) { + + throw buildException(e); + + } + + + + } + + private IntegrationException buildException(Exception ex) { + + + if(ex instanceof CardException) { + CardException e = (CardException)ex; + // Since it's a decline, CardException will be caught + //System.out.println("Status is: " + e.getCode()); + //System.out.println("Message is: " + e.getMessage()); + + + /** + * + invalid_number The card number is not a valid credit card number. + invalid_expiry_month The card's expiration month is invalid. + invalid_expiry_year The card's expiration year is invalid. + invalid_cvc The card's security code is invalid. + incorrect_number The card number is incorrect. + expired_card The card has expired. + incorrect_cvc The card's security code is incorrect. + incorrect_zip The card's zip code failed validation. + card_declined The card was declined. + missing There is no card on a customer that is being charged. + processing_error An error occurred while processing the card. + rate_limit An error occurred due to requests hitting the API too quickly. Please let us know if you're consistently running into this error. + */ + + + String declineCode = e.getDeclineCode(); + + if("card_declined".equals(declineCode)) { + IntegrationException te = new IntegrationException( + "Can't process stripe message " + e.getMessage()); + te.setExceptionType(IntegrationException.EXCEPTION_PAYMENT_DECLINED); + te.setMessageCode("message.payment.declined"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + return te; + } + + if("invalid_number".equals(declineCode)) { + IntegrationException te = new IntegrationException( + "Can't process stripe message " + e.getMessage()); + te.setExceptionType(IntegrationException.EXCEPTION_VALIDATION); + te.setMessageCode("messages.error.creditcard.number"); + te.setErrorCode(IntegrationException.EXCEPTION_VALIDATION); + return te; + } + + if("invalid_expiry_month".equals(declineCode)) { + IntegrationException te = new IntegrationException( + "Can't process stripe message " + e.getMessage()); + te.setExceptionType(IntegrationException.EXCEPTION_VALIDATION); + te.setMessageCode("messages.error.creditcard.dateformat"); + te.setErrorCode(IntegrationException.EXCEPTION_VALIDATION); + return te; + } + + if("invalid_expiry_year".equals(declineCode)) { + IntegrationException te = new IntegrationException( + "Can't process stripe message " + e.getMessage()); + te.setExceptionType(IntegrationException.EXCEPTION_VALIDATION); + te.setMessageCode("messages.error.creditcard.dateformat"); + te.setErrorCode(IntegrationException.EXCEPTION_VALIDATION); + return te; + } + + if("invalid_cvc".equals(declineCode)) { + IntegrationException te = new IntegrationException( + "Can't process stripe message " + e.getMessage()); + te.setExceptionType(IntegrationException.EXCEPTION_VALIDATION); + te.setMessageCode("messages.error.creditcard.cvc"); + te.setErrorCode(IntegrationException.EXCEPTION_VALIDATION); + return te; + } + + if("incorrect_number".equals(declineCode)) { + IntegrationException te = new IntegrationException( + "Can't process stripe message " + e.getMessage()); + te.setExceptionType(IntegrationException.EXCEPTION_VALIDATION); + te.setMessageCode("messages.error.creditcard.number"); + te.setErrorCode(IntegrationException.EXCEPTION_VALIDATION); + return te; + } + + if("incorrect_cvc".equals(declineCode)) { + IntegrationException te = new IntegrationException( + "Can't process stripe message " + e.getMessage()); + te.setExceptionType(IntegrationException.EXCEPTION_VALIDATION); + te.setMessageCode("messages.error.creditcard.cvc"); + te.setErrorCode(IntegrationException.EXCEPTION_VALIDATION); + return te; + } + + //nothing good so create generic error + IntegrationException te = new IntegrationException( + "Can't process stripe card " + e.getMessage()); + te.setExceptionType(IntegrationException.EXCEPTION_VALIDATION); + te.setMessageCode("messages.error.creditcard.number"); + te.setErrorCode(IntegrationException.EXCEPTION_VALIDATION); + return te; + + + + } else if (ex instanceof InvalidRequestException) { + LOGGER.error("InvalidRequest error with stripe", ex.getMessage()); + InvalidRequestException e =(InvalidRequestException)ex; + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing invalid payment parameters"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("messages.error.creditcard.number"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + return te; + + } else if (ex instanceof AuthenticationException) { + LOGGER.error("Authentication error with stripe", ex.getMessage()); + AuthenticationException e = (AuthenticationException)ex; + // Authentication with Stripe's API failed + // (maybe you changed API keys recently) + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing invalid payment parameters"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + return te; + + } /*else if (ex instanceof APIConnectionException) { // DEPRECATED THIS EXCEPTION TYPE + LOGGER.error("API connection error with stripe", ex.getMessage()); + APIConnectionException e = (APIConnectionException)ex; + // Network communication with Stripe failed + IntegrationException te = new IntegrationException( + "Can't process Stripe, missing invalid payment parameters"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + return te; + } */else if (ex instanceof StripeException) { + LOGGER.error("Error with stripe", ex.getMessage()); + StripeException e = (StripeException)ex; + // Display a very generic error to the user, and maybe send + // yourself an email + IntegrationException te = new IntegrationException( + "Can't process Stripe authorize, missing invalid payment parameters"); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + return te; + + + + } else if (ex instanceof Exception) { + LOGGER.error("Stripe module error", ex.getMessage()); + if(ex instanceof IntegrationException) { + return (IntegrationException)ex; + } else { + IntegrationException te = new IntegrationException( + "Can't process Stripe authorize, exception", ex); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + return te; + } + + + } else { + LOGGER.error("Stripe module error", ex.getMessage()); + IntegrationException te = new IntegrationException( + "Can't process Stripe authorize, exception", ex); + te.setExceptionType(IntegrationException.TRANSACTION_EXCEPTION); + te.setMessageCode("message.payment.error"); + te.setErrorCode(IntegrationException.TRANSACTION_EXCEPTION); + return te; + } + + } + + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/CustomShippingQuoteRules.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/CustomShippingQuoteRules.java new file mode 100755 index 0000000000..374c286cbe --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/CustomShippingQuoteRules.java @@ -0,0 +1,189 @@ +package com.salesmanager.core.business.modules.integration.shipping.impl; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.kie.api.runtime.KieSession; +import org.kie.internal.io.ResourceFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.salesmanager.core.business.configuration.DroolsBeanFactory; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.shipping.PackageDetails; +import com.salesmanager.core.model.shipping.ShippingConfiguration; +import com.salesmanager.core.model.shipping.ShippingOption; +import com.salesmanager.core.model.shipping.ShippingOrigin; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.model.system.CustomIntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.modules.constants.Constants; +import com.salesmanager.core.modules.integration.IntegrationException; +import com.salesmanager.core.modules.integration.shipping.model.ShippingQuoteModule; + + +public class CustomShippingQuoteRules implements ShippingQuoteModule { + + private static final Logger LOGGER = LoggerFactory.getLogger(CustomShippingQuoteRules.class); + + @Inject + private DroolsBeanFactory droolsBeanFactory; + + public final static String MODULE_CODE = "customQuotesRules"; + + @Override + public void validateModuleConfiguration( + IntegrationConfiguration integrationConfiguration, + MerchantStore store) throws IntegrationException { + // Not used + + } + + @Override + public CustomIntegrationConfiguration getCustomModuleConfiguration( + MerchantStore store) throws IntegrationException { + // Not used + return null; + } + + @Override + public List getShippingQuotes(ShippingQuote quote, + List packages, BigDecimal orderTotal, + Delivery delivery, ShippingOrigin origin, MerchantStore store, + IntegrationConfiguration configuration, IntegrationModule module, + ShippingConfiguration shippingConfiguration, Locale locale) + throws IntegrationException { + + + + Validate.notNull(delivery, "Delivery cannot be null"); + Validate.notNull(delivery.getCountry(), "Delivery.country cannot be null"); + Validate.notNull(packages, "packages cannot be null"); + Validate.notEmpty(packages, "packages cannot be empty"); + + //requires the postal code + if(StringUtils.isBlank(delivery.getPostalCode())) { + return null; + } + + Double distance = null; + + if(quote!=null) { + //look if distance has been calculated + if(quote.getQuoteInformations()!=null) { + if(quote.getQuoteInformations().containsKey(Constants.DISTANCE_KEY)) { + distance = (Double)quote.getQuoteInformations().get(Constants.DISTANCE_KEY); + } + } + } + + //calculate volume (L x W x H) + Double volume = null; + Double weight = 0D; + Double size = null; + //calculate weight + for(PackageDetails pack : packages) { + weight = weight + pack.getShippingWeight(); + Double tmpVolume = pack.getShippingHeight() * pack.getShippingLength() * pack.getShippingWidth(); + if(volume == null || tmpVolume > volume) { //take the largest volume + volume = tmpVolume; + } + //largest size + List sizeList = new ArrayList(); + sizeList.add(pack.getShippingHeight()); + sizeList.add(pack.getShippingWidth()); + sizeList.add(pack.getShippingLength()); + Double maxSize = Collections.max(sizeList); + if(size==null || maxSize > size) { + size = maxSize; + } + } + + //Build a ShippingInputParameters + ShippingInputParameters inputParameters = new ShippingInputParameters(); + + inputParameters.setWeight((long)weight.doubleValue()); + inputParameters.setCountry(delivery.getCountry().getIsoCode()); + inputParameters.setProvince("*"); + inputParameters.setModuleName(module.getCode()); + + if(delivery.getZone() != null && delivery.getZone().getCode()!=null) { + inputParameters.setProvince(delivery.getZone().getCode()); + } + + if(distance!=null) { + double ddistance = distance; + long ldistance = (long)ddistance; + inputParameters.setDistance(ldistance); + } + + if(volume!=null) { + inputParameters.setVolume((long)volume.doubleValue()); + } + + List options = quote.getShippingOptions(); + + if(options == null) { + options = new ArrayList(); + quote.setShippingOptions(options); + } + + + + LOGGER.debug("Setting input parameters " + inputParameters.toString()); + + + KieSession kieSession=droolsBeanFactory.getKieSession(ResourceFactory.newClassPathResource("com/salesmanager/drools/rules/PriceByDistance.drl")); + + DecisionResponse resp = new DecisionResponse(); + + kieSession.insert(inputParameters); + kieSession.setGlobal("decision",resp); + kieSession.fireAllRules(); + //System.out.println(resp.getCustomPrice()); + + if(resp.getCustomPrice() != null) { + + ShippingOption shippingOption = new ShippingOption(); + + + shippingOption.setOptionPrice(new BigDecimal(resp.getCustomPrice())); + shippingOption.setShippingModuleCode(MODULE_CODE); + shippingOption.setOptionCode(MODULE_CODE); + shippingOption.setOptionId(MODULE_CODE); + + options.add(shippingOption); + } + + + return options; + + + } + +/* public StatelessKnowledgeSession getShippingPriceRule() { + return shippingPriceRule; + } + + public void setShippingPriceRule(StatelessKnowledgeSession shippingPriceRule) { + this.shippingPriceRule = shippingPriceRule; + } + + public KnowledgeBase getKbase() { + return kbase; + } + + public void setKbase(KnowledgeBase kbase) { + this.kbase = kbase; + }*/ + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/CustomWeightBasedShippingQuote.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/CustomWeightBasedShippingQuote.java new file mode 100755 index 0000000000..d58df1977c --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/CustomWeightBasedShippingQuote.java @@ -0,0 +1,160 @@ +package com.salesmanager.core.business.modules.integration.shipping.impl; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.system.MerchantConfigurationService; +import com.salesmanager.core.business.utils.ProductPriceUtils; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.shipping.PackageDetails; +import com.salesmanager.core.model.shipping.ShippingBasisType; +import com.salesmanager.core.model.shipping.ShippingConfiguration; +import com.salesmanager.core.model.shipping.ShippingOption; +import com.salesmanager.core.model.shipping.ShippingOrigin; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.model.system.CustomIntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.model.system.MerchantConfiguration; +import com.salesmanager.core.modules.integration.IntegrationException; +import com.salesmanager.core.modules.integration.shipping.model.CustomShippingQuoteWeightItem; +import com.salesmanager.core.modules.integration.shipping.model.CustomShippingQuotesConfiguration; +import com.salesmanager.core.modules.integration.shipping.model.CustomShippingQuotesRegion; +import com.salesmanager.core.modules.integration.shipping.model.ShippingQuoteModule; + + +public class CustomWeightBasedShippingQuote implements ShippingQuoteModule { + + public final static String MODULE_CODE = "weightBased"; + private final static String CUSTOM_WEIGHT = "CUSTOM_WEIGHT"; + + @Inject + private MerchantConfigurationService merchantConfigurationService; + + @Inject + private ProductPriceUtils productPriceUtils; + + + @Override + public void validateModuleConfiguration( + IntegrationConfiguration integrationConfiguration, + MerchantStore store) throws IntegrationException { + + + //not used, it has its own controller with complex validators + + } + + + @Override + public CustomIntegrationConfiguration getCustomModuleConfiguration( + MerchantStore store) throws IntegrationException { + + try { + + MerchantConfiguration configuration = merchantConfigurationService.getMerchantConfiguration(MODULE_CODE, store); + + if(configuration!=null) { + String value = configuration.getValue(); + ObjectMapper mapper = new ObjectMapper(); + try { + return mapper.readValue(value, CustomShippingQuotesConfiguration.class); + } catch(Exception e) { + throw new ServiceException("Cannot parse json string " + value); + } + + } else { + CustomShippingQuotesConfiguration custom = new CustomShippingQuotesConfiguration(); + custom.setModuleCode(MODULE_CODE); + return custom; + } + + } catch (Exception e) { + throw new IntegrationException(e); + } + + + } + + @Override + public List getShippingQuotes( + ShippingQuote shippingQuote, + List packages, BigDecimal orderTotal, + Delivery delivery, ShippingOrigin origin, MerchantStore store, + IntegrationConfiguration configuration, IntegrationModule module, + ShippingConfiguration shippingConfiguration, Locale locale) + throws IntegrationException { + + if(StringUtils.isBlank(delivery.getPostalCode())) { + return null; + } + + //get configuration + CustomShippingQuotesConfiguration customConfiguration = (CustomShippingQuotesConfiguration)this.getCustomModuleConfiguration(store); + + + List regions = customConfiguration.getRegions(); + + ShippingBasisType shippingType = shippingConfiguration.getShippingBasisType(); + ShippingOption shippingOption = null; + try { + + + for(CustomShippingQuotesRegion region : customConfiguration.getRegions()) { + + for(String countryCode : region.getCountries()) { + if(countryCode.equals(delivery.getCountry().getIsoCode())) { + + + //determine shipping weight + double weight = 0; + for(PackageDetails packageDetail : packages) { + weight = weight + packageDetail.getShippingWeight(); + } + + //see the price associated with the width + List quoteItems = region.getQuoteItems(); + for(CustomShippingQuoteWeightItem quoteItem : quoteItems) { + if(weight<= quoteItem.getMaximumWeight()) { + shippingOption = new ShippingOption(); + shippingOption.setOptionCode(new StringBuilder().append(CUSTOM_WEIGHT).toString()); + shippingOption.setOptionId(new StringBuilder().append(CUSTOM_WEIGHT).append("_").append(region.getCustomRegionName()).toString()); + shippingOption.setOptionPrice(quoteItem.getPrice()); + shippingOption.setOptionPriceText(productPriceUtils.getStoreFormatedAmountWithCurrency(store, quoteItem.getPrice())); + break; + } + } + + } + + + } + + } + + if(shippingOption!=null) { + List options = new ArrayList(); + options.add(shippingOption); + return options; + } + + return null; + + } catch (Exception e) { + throw new IntegrationException(e); + } + + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/DecisionResponse.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/DecisionResponse.java new file mode 100644 index 0000000000..188c8e84cb --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/DecisionResponse.java @@ -0,0 +1,24 @@ +package com.salesmanager.core.business.modules.integration.shipping.impl; + +public class DecisionResponse { + + private String moduleName; + private String customPrice; + + public String getModuleName() { + return moduleName; + } + + public void setModuleName(String moduleName) { + this.moduleName = moduleName; + } + + public String getCustomPrice() { + return customPrice; + } + + public void setCustomPrice(String customPrice) { + this.customPrice = customPrice; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/DefaultPackagingImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/DefaultPackagingImpl.java new file mode 100755 index 0000000000..39a2f0ded2 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/DefaultPackagingImpl.java @@ -0,0 +1,436 @@ +package com.salesmanager.core.business.modules.integration.shipping.impl; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import javax.inject.Inject; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.shipping.ShippingService; +import com.salesmanager.core.business.services.system.MerchantLogService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.shipping.PackageDetails; +import com.salesmanager.core.model.shipping.ShippingConfiguration; +import com.salesmanager.core.model.shipping.ShippingProduct; +import com.salesmanager.core.model.system.MerchantLog; +import com.salesmanager.core.modules.integration.shipping.model.Packaging; + +public class DefaultPackagingImpl implements Packaging { + + + @Inject + private ShippingService shippingService; + + @Inject + private MerchantLogService merchantLogService; + + /** default dimensions **/ + private final static Double defaultWeight = 1D; + private final static Double defaultHeight = 4D; + private final static Double defaultLength = 4D; + private final static Double defaultWidth = 4D; + + @Override + public List getBoxPackagesDetails( + List products, MerchantStore store) + throws ServiceException { + + + if (products == null) { + throw new ServiceException("Product list cannot be null !!"); + } + + double width = 0; + double length = 0; + double height = 0; + double weight = 0; + double maxweight = 0; + + //int treshold = 0; + + + ShippingConfiguration shippingConfiguration = shippingService.getShippingConfiguration(store); + if(shippingConfiguration==null) { + throw new ServiceException("ShippingConfiguration not found for merchant " + store.getCode()); + } + + width = (double) shippingConfiguration.getBoxWidth(); + length = (double) shippingConfiguration.getBoxLength(); + height = (double) shippingConfiguration.getBoxHeight(); + weight = shippingConfiguration.getBoxWeight(); + maxweight = shippingConfiguration.getMaxWeight(); + + + + List boxes = new ArrayList(); + + // maximum number of boxes + int maxBox = 100; + int iterCount = 0; + + List individualProducts = new ArrayList(); + + // need to put items individually + for(ShippingProduct shippingProduct : products){ + + Product product = shippingProduct.getProduct(); + if (product.isProductVirtual()) { + continue; + } + + int qty = shippingProduct.getQuantity(); + + Set attrs = shippingProduct.getProduct().getAttributes(); + + // set attributes values + BigDecimal w = product.getProductWeight(); + BigDecimal h = product.getProductHeight(); + BigDecimal l = product.getProductLength(); + BigDecimal wd = product.getProductWidth(); + if(w==null) { + w = new BigDecimal(defaultWeight); + } + if(h==null) { + h = new BigDecimal(defaultHeight); + } + if(l==null) { + l = new BigDecimal(defaultLength); + } + if(wd==null) { + wd = new BigDecimal(defaultWidth); + } + if (attrs != null && attrs.size() > 0) { + for(ProductAttribute attribute : attrs) { + if(attribute.getProductAttributeWeight()!=null) { + w = w.add(attribute.getProductAttributeWeight()); + } + } + } + + + + if (qty > 1) { + + for (int i = 1; i <= qty; i++) { + Product temp = new Product(); + temp.setProductHeight(h); + temp.setProductLength(l); + temp.setProductWidth(wd); + temp.setProductWeight(w); + temp.setAttributes(product.getAttributes()); + temp.setDescriptions(product.getDescriptions()); + individualProducts.add(temp); + } + } else { + Product temp = new Product(); + temp.setProductHeight(h); + temp.setProductLength(l); + temp.setProductWidth(wd); + temp.setProductWeight(w); + temp.setAttributes(product.getAttributes()); + temp.setDescriptions(product.getDescriptions()); + individualProducts.add(temp); + } + iterCount++; + } + + if (iterCount == 0) { + return null; + } + + int productCount = individualProducts.size(); + + List boxesList = new ArrayList(); + + //start the creation of boxes + PackingBox box = new PackingBox(); + // set box max volume + double maxVolume = width * length * height; + + if (maxVolume == 0 || maxweight == 0) { + + merchantLogService.save(new MerchantLog(store,"shipping","Check shipping box configuration, it has a volume of " + + maxVolume + " and a maximum weight of " + + maxweight + + ". Those values must be greater than 0.")); + + throw new ServiceException("Product configuration exceeds box configuraton"); + + + } + + + box.setVolumeLeft(maxVolume); + box.setWeightLeft(maxweight); + + boxesList.add(box);//assign first box + + //int boxCount = 1; + List assignedProducts = new ArrayList(); + + // calculate the volume for the next object + if (assignedProducts.size() > 0) { + individualProducts.removeAll(assignedProducts); + assignedProducts = new ArrayList(); + } + + boolean productAssigned = false; + + for(Product p : individualProducts) { + + //Set attributes = p.getAttributes(); + productAssigned = false; + + double productWeight = p.getProductWeight().doubleValue(); + + + // validate if product fits in the box + if (p.getProductWidth().doubleValue() > width + || p.getProductHeight().doubleValue() > height + || p.getProductLength().doubleValue() > length) { + // log message to customer + merchantLogService.save(new MerchantLog(store,"shipping","Product " + + p.getSku() + + " has a demension larger than the box size specified. Will use per item calculation.")); + throw new ServiceException("Product configuration exceeds box configuraton"); + + } + + if (productWeight > maxweight) { + merchantLogService.save(new MerchantLog(store,"shipping","Product " + + p.getSku() + + " has a weight larger than the box maximum weight specified. Will use per item calculation.")); + + throw new ServiceException("Product configuration exceeds box configuraton"); + + } + + double productVolume = (p.getProductWidth().doubleValue() + * p.getProductHeight().doubleValue() * p + .getProductLength().doubleValue()); + + if (productVolume == 0) { + + merchantLogService.save(new MerchantLog(store,"shipping","Product " + + p.getSku() + + " has one of the dimension set to 0 and therefore cannot calculate the volume")); + + throw new ServiceException("Product configuration exceeds box configuraton"); + + + } + + if (productVolume > maxVolume) { + + throw new ServiceException("Product configuration exceeds box configuraton"); + + } + + //List boxesList = boxesList; + + // try each box + //Iterator boxIter = boxesList.iterator(); + for (PackingBox pbox : boxesList) { + double volumeLeft = pbox.getVolumeLeft(); + double weightLeft = pbox.getWeightLeft(); + + if ((volumeLeft * .75) >= productVolume + && pbox.getWeightLeft() >= productWeight) {// fit the item + // in this + // box + // fit in the current box + volumeLeft = volumeLeft - productVolume; + pbox.setVolumeLeft(volumeLeft); + weightLeft = weightLeft - productWeight; + pbox.setWeightLeft(weightLeft); + + assignedProducts.add(p); + productCount--; + + double w = pbox.getWeight(); + w = w + productWeight; + pbox.setWeight(w); + productAssigned = true; + maxBox--; + break; + + } + + } + + if (!productAssigned) {// create a new box + + box = new PackingBox(); + // set box max volume + box.setVolumeLeft(maxVolume); + box.setWeightLeft(maxweight); + + boxesList.add(box); + + double volumeLeft = box.getVolumeLeft() - productVolume; + box.setVolumeLeft(volumeLeft); + double weightLeft = box.getWeightLeft() - productWeight; + box.setWeightLeft(weightLeft); + assignedProducts.add(p); + productCount--; + double w = box.getWeight(); + w = w + productWeight; + box.setWeight(w); + maxBox--; + } + + } + + // now prepare the shipping info + + // number of boxes + + //Iterator ubIt = usedBoxesList.iterator(); + + System.out.println("###################################"); + System.out.println("Number of boxes " + boxesList.size()); + System.out.println("###################################"); + + for(PackingBox pb : boxesList) { + PackageDetails details = new PackageDetails(); + details.setShippingHeight(height); + details.setShippingLength(length); + details.setShippingWeight(weight + box.getWeight()); + details.setShippingWidth(width); + details.setItemName(store.getCode()); + boxes.add(details); + } + + return boxes; + + } + + @Override + public List getItemPackagesDetails( + List products, MerchantStore store) + throws ServiceException { + + + List packages = new ArrayList(); + for(ShippingProduct shippingProduct : products) { + Product product = shippingProduct.getProduct(); + + if (product.isProductVirtual()) { + continue; + } + + //BigDecimal weight = product.getProductWeight(); + Set attributes = product.getAttributes(); + // set attributes values + BigDecimal w = product.getProductWeight(); + BigDecimal h = product.getProductHeight(); + BigDecimal l = product.getProductLength(); + BigDecimal wd = product.getProductWidth(); + if(w==null) { + w = new BigDecimal(defaultWeight); + } + if(h==null) { + h = new BigDecimal(defaultHeight); + } + if(l==null) { + l = new BigDecimal(defaultLength); + } + if(wd==null) { + wd = new BigDecimal(defaultWidth); + } + if (attributes != null && attributes.size() > 0) { + for(ProductAttribute attribute : attributes) { + if(attribute.getAttributeAdditionalWeight()!=null && attribute.getProductAttributeWeight() !=null) { + w = w.add(attribute.getProductAttributeWeight()); + } + } + } + + + + if (shippingProduct.getQuantity() == 1) { + PackageDetails detail = new PackageDetails(); + + + detail.setShippingHeight(h + .doubleValue()); + detail.setShippingLength(l + .doubleValue()); + detail.setShippingWeight(w.doubleValue()); + detail.setShippingWidth(wd.doubleValue()); + detail.setShippingQuantity(shippingProduct.getQuantity()); + String description = "item"; + if(product.getDescriptions().size()>0) { + description = product.getDescriptions().iterator().next().getName(); + } + detail.setItemName(description); + + packages.add(detail); + } else if (shippingProduct.getQuantity() > 1) { + for (int i = 0; i < shippingProduct.getQuantity(); i++) { + PackageDetails detail = new PackageDetails(); + detail.setShippingHeight(h + .doubleValue()); + detail.setShippingLength(l + .doubleValue()); + detail.setShippingWeight(w.doubleValue()); + detail.setShippingWidth(wd + .doubleValue()); + detail.setShippingQuantity(1);//issue seperate shipping + String description = "item"; + if(product.getDescriptions().size()>0) { + description = product.getDescriptions().iterator().next().getName(); + } + detail.setItemName(description); + + packages.add(detail); + } + } + } + + return packages; + + + + } + + +} + + +class PackingBox { + + private double volumeLeft; + private double weightLeft; + private double weight; + + public double getVolumeLeft() { + return volumeLeft; + } + + public void setVolumeLeft(double volumeLeft) { + this.volumeLeft = volumeLeft; + } + + public double getWeight() { + return weight; + } + + public void setWeight(double weight) { + this.weight = weight; + } + + public double getWeightLeft() { + return weightLeft; + } + + public void setWeightLeft(double weightLeft) { + this.weightLeft = weightLeft; + } + +} + diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/PriceByDistanceShippingQuoteRules.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/PriceByDistanceShippingQuoteRules.java new file mode 100755 index 0000000000..e9e485f84d --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/PriceByDistanceShippingQuoteRules.java @@ -0,0 +1,133 @@ +package com.salesmanager.core.business.modules.integration.shipping.impl; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Objects; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.shipping.PackageDetails; +import com.salesmanager.core.model.shipping.ShippingConfiguration; +import com.salesmanager.core.model.shipping.ShippingOption; +import com.salesmanager.core.model.shipping.ShippingOrigin; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.model.system.CustomIntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.modules.constants.Constants; +import com.salesmanager.core.modules.integration.IntegrationException; +import com.salesmanager.core.modules.integration.shipping.model.ShippingQuoteModule; + + +/** + * Requires to set pre-processor distance calculator + * pre-processor calculates the distance (in kilometers [can be changed to miles]) based on delivery address + * when that module is invoked during process it will calculate the price + * DISTANCE * PRICE/KM + * @author carlsamson + * + */ +public class PriceByDistanceShippingQuoteRules implements ShippingQuoteModule { + + private static final Logger LOGGER = LoggerFactory.getLogger(PriceByDistanceShippingQuoteRules.class); + + public final static String MODULE_CODE = "priceByDistance"; + + @Override + public void validateModuleConfiguration( + IntegrationConfiguration integrationConfiguration, + MerchantStore store) throws IntegrationException { + // Not used + + } + + @Override + public CustomIntegrationConfiguration getCustomModuleConfiguration( + MerchantStore store) throws IntegrationException { + // Not used + return null; + } + + @Override + public List getShippingQuotes(ShippingQuote quote, + List packages, BigDecimal orderTotal, + Delivery delivery, ShippingOrigin origin, MerchantStore store, + IntegrationConfiguration configuration, IntegrationModule module, + ShippingConfiguration shippingConfiguration, Locale locale) + throws IntegrationException { + + + + Validate.notNull(delivery, "Delivery cannot be null"); + Validate.notNull(delivery.getCountry(), "Delivery.country cannot be null"); + Validate.notNull(packages, "packages cannot be null"); + Validate.notEmpty(packages, "packages cannot be empty"); + + //requires the postal code + if(StringUtils.isBlank(delivery.getPostalCode())) { + return null; + } + + Double distance = null; + + //look if distance has been calculated + if (Objects.nonNull(quote) && Objects.nonNull(quote.getQuoteInformations())) { + if (quote.getQuoteInformations().containsKey(Constants.DISTANCE_KEY)) { + distance = (Double) quote.getQuoteInformations().get(Constants.DISTANCE_KEY); + } + } + + if(distance==null) { + return null; + } + + //maximum distance TODO configure from admin + if(distance > 150D) { + return null; + } + + List options = quote.getShippingOptions(); + + if(options == null) { + options = new ArrayList<>(); + quote.setShippingOptions(options); + } + + BigDecimal price = null; + + if(distance<=20) { + price = new BigDecimal(2);//TODO from the admin + } else { + price = new BigDecimal(3);//TODO from the admin + } + BigDecimal total = new BigDecimal(distance).multiply(price); + + if(distance < 1) { //minimum 1 unit + distance = 1D; + } + + + ShippingOption shippingOption = new ShippingOption(); + + + shippingOption.setOptionPrice(total); + shippingOption.setShippingModuleCode(MODULE_CODE); + shippingOption.setOptionCode(MODULE_CODE); + shippingOption.setOptionId(MODULE_CODE); + + options.add(shippingOption); + + + return options; + + + } + +} \ No newline at end of file diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/ShippingDecisionPreProcessorImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/ShippingDecisionPreProcessorImpl.java new file mode 100755 index 0000000000..49d8ea8324 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/ShippingDecisionPreProcessorImpl.java @@ -0,0 +1,179 @@ +package com.salesmanager.core.business.modules.integration.shipping.impl; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.kie.api.runtime.KieSession; +import org.kie.internal.io.ResourceFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.salesmanager.core.business.configuration.DroolsBeanFactory; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.shipping.PackageDetails; +import com.salesmanager.core.model.shipping.ShippingConfiguration; +import com.salesmanager.core.model.shipping.ShippingOrigin; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.modules.constants.Constants; +import com.salesmanager.core.modules.integration.IntegrationException; +import com.salesmanager.core.modules.integration.shipping.model.ShippingQuotePrePostProcessModule; + +/** + * Decides which shipping method is going to be used based on a decision table + * @author carlsamson + * + */ +public class ShippingDecisionPreProcessorImpl implements ShippingQuotePrePostProcessModule { + + private static final Logger LOGGER = LoggerFactory.getLogger(ShippingDecisionPreProcessorImpl.class); + + private final static String MODULE_CODE = "shippingDecisionModule"; + + @Inject + private DroolsBeanFactory droolsBeanFactory; + + //private StatelessKnowledgeSession shippingMethodDecision; + + //private KnowledgeBase kbase; + + //@Inject + //KieContainer kieShippingDecisionContainer; + + @Override + public void prePostProcessShippingQuotes( + ShippingQuote quote, + List packages, + BigDecimal orderTotal, + Delivery delivery, + ShippingOrigin origin, + MerchantStore store, + IntegrationConfiguration globalShippingConfiguration, + IntegrationModule currentModule, + ShippingConfiguration shippingConfiguration, + List allModules, + Locale locale) + throws IntegrationException { + + + Validate.notNull(delivery, "Delivery cannot be null"); + Validate.notNull(currentModule, "IntegrationModule cannot be null"); + Validate.notNull(delivery.getCountry(), "Delivery.country cannot be null"); + Validate.notNull(allModules, "List cannot be null"); + Validate.notNull(packages, "packages cannot be null"); + Validate.notEmpty(packages, "packages cannot be empty"); + + Double distance = null; + + if(quote!=null) { + //look if distance has been calculated + if(quote.getQuoteInformations()!=null) { + if(quote.getQuoteInformations().containsKey(Constants.DISTANCE_KEY)) { + distance = (Double)quote.getQuoteInformations().get(Constants.DISTANCE_KEY); + } + } + } + + //calculate volume (L x W x H) + Double volume = null; + Double weight = 0D; + Double size = null; + //calculate weight, volume and largest size + for(PackageDetails pack : packages) { + weight = weight + pack.getShippingWeight(); + Double tmpVolume = pack.getShippingHeight() * pack.getShippingLength() * pack.getShippingWidth(); + if(volume == null || tmpVolume > volume) { //take the largest volume + volume = tmpVolume; + } + //largest size + List sizeList = new ArrayList(); + sizeList.add(pack.getShippingHeight()); + sizeList.add(pack.getShippingLength()); + sizeList.add(pack.getShippingWidth()); + Double maxSize = Collections.max(sizeList); + if(size==null || maxSize > size) { + size = maxSize; + } + } + + //Build a ShippingInputParameters + ShippingInputParameters inputParameters = new ShippingInputParameters(); + + inputParameters.setWeight((long)weight.doubleValue()); + inputParameters.setCountry(delivery.getCountry().getIsoCode()); + if(delivery.getZone()!=null && delivery.getZone().getCode()!=null) { + inputParameters.setProvince(delivery.getZone().getCode()); + } else { + inputParameters.setProvince(delivery.getState()); + } + //inputParameters.setModuleName(currentModule.getCode()); + + + if(size!=null) { + inputParameters.setSize((long)size.doubleValue()); + } + + if(distance!=null) { + double ddistance = distance; + long ldistance = (long)ddistance; + inputParameters.setDistance(ldistance); + } + + if(volume!=null) { + inputParameters.setVolume((long)volume.doubleValue()); + } + + LOGGER.debug("Setting input parameters " + inputParameters.toString()); + System.out.println(inputParameters.toString()); + + + /** + * New code + */ + + KieSession kieSession=droolsBeanFactory.getKieSession(ResourceFactory.newClassPathResource("com/salesmanager/drools/rules/ShippingDecision.drl")); + + DecisionResponse resp = new DecisionResponse(); + + kieSession.insert(inputParameters); + kieSession.setGlobal("decision",resp); + kieSession.fireAllRules(); + //System.out.println(resp.getModuleName()); + inputParameters.setModuleName(resp.getModuleName()); + + LOGGER.debug("Using shipping nodule " + inputParameters.getModuleName()); + + if(!StringUtils.isBlank(inputParameters.getModuleName())) { + for(IntegrationModule toBeUsed : allModules) { + if(toBeUsed.getCode().equals(inputParameters.getModuleName())) { + quote.setCurrentShippingModule(toBeUsed); + break; + } + } + } + + } + + + @Override + public String getModuleCode() { + return MODULE_CODE; + } + + + + + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/ShippingDistancePreProcessorImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/ShippingDistancePreProcessorImpl.java new file mode 100644 index 0000000000..2da170ce21 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/ShippingDistancePreProcessorImpl.java @@ -0,0 +1,226 @@ +package com.salesmanager.core.business.modules.integration.shipping.impl; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import com.google.maps.DistanceMatrixApi; +import com.google.maps.GeoApiContext; +import com.google.maps.GeocodingApi; +import com.google.maps.model.Distance; +import com.google.maps.model.DistanceMatrix; +import com.google.maps.model.DistanceMatrixRow; +import com.google.maps.model.GeocodingResult; +import com.google.maps.model.LatLng; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.shipping.PackageDetails; +import com.salesmanager.core.model.shipping.ShippingConfiguration; +import com.salesmanager.core.model.shipping.ShippingOrigin; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.modules.constants.Constants; +import com.salesmanager.core.modules.integration.IntegrationException; +import com.salesmanager.core.modules.integration.shipping.model.ShippingQuotePrePostProcessModule; + +/** + * Uses google api to get lng, lat and distance in km for a given delivery address + * The route will be displayed on a map to the end user and available + * from the admin section + * + * The module can be configured to use miles by changing distance.inMeters + * + * To use this pre-processor you will need a google api-key + * + * Access google developers console + * https://console.developers.google.com/project + * + * Geocoding + * Distance Matrix + * Directions + * + * Create new key for server application + * Copy API key + * https://console.developers.google.com + * + * https://developers.google.com/maps/documentation/webservices/client-library + * https://github.com/googlemaps/google-maps-services-java/tree/master/src/test/java/com/google/maps + * + * @author carlsamson + * + */ +@Component("shippingDistancePreProcessor") +public class ShippingDistancePreProcessorImpl implements ShippingQuotePrePostProcessModule { + + private static final Logger LOGGER = LoggerFactory.getLogger(ShippingDistancePreProcessorImpl.class); + + private final static String BLANK = " "; + + private final static String MODULE_CODE = "shippingDistanceModule"; + + @Value("${config.shippingDistancePreProcessor.apiKey}") + private String apiKey; + + @Value("#{'${config.shippingDistancePreProcessor.acceptedZones}'.split(',')}") + private List allowedZonesCodes = null; + + + + public List getAllowedZonesCodes() { + return allowedZonesCodes; + } + + + + + + public void setAllowedZonesCodes(List allowedZonesCodes) { + this.allowedZonesCodes = allowedZonesCodes; + } + + + + + + public void prePostProcessShippingQuotes(ShippingQuote quote, + List packages, BigDecimal orderTotal, + Delivery delivery, ShippingOrigin origin, MerchantStore store, + IntegrationConfiguration globalShippingConfiguration, + IntegrationModule currentModule, + ShippingConfiguration shippingConfiguration, + List allModules, Locale locale) + throws IntegrationException { + + + /** which destinations are supported by this module **/ + + if(delivery.getZone()==null) { + return; + } + + boolean zoneAllowed = false; + if(allowedZonesCodes!=null) { + for(String zoneCode : allowedZonesCodes) { + if(zoneCode.equals(delivery.getZone().getCode())) { + zoneAllowed = true; + break; + } + } + } + + if(!zoneAllowed) { + return; + } + + if(StringUtils.isBlank(delivery.getPostalCode())) { + return; + } + + Validate.notNull(apiKey, "Requires the configuration of google apiKey"); + + GeoApiContext context = new GeoApiContext().setApiKey(apiKey); + + //build origin address + StringBuilder originAddress = new StringBuilder(); + + originAddress.append(origin.getAddress()).append(BLANK) + .append(origin.getCity()).append(BLANK) + .append(origin.getPostalCode()).append(BLANK); + + if(!StringUtils.isBlank(origin.getState())) { + originAddress.append(origin.getState()).append(" "); + } + if(origin.getZone()!=null) { + originAddress.append(origin.getZone().getCode()).append(" "); + } + originAddress.append(origin.getCountry().getIsoCode()); + + + //build destination address + StringBuilder destinationAddress = new StringBuilder(); + + destinationAddress.append(delivery.getAddress()).append(BLANK); + if(!StringUtils.isBlank(delivery.getCity())) { + destinationAddress.append(delivery.getCity()).append(BLANK); + } + destinationAddress.append(delivery.getPostalCode()).append(BLANK); + + if(!StringUtils.isBlank(delivery.getState())) { + destinationAddress.append(delivery.getState()).append(" "); + } + if(delivery.getZone()!=null) { + destinationAddress.append(delivery.getZone().getCode()).append(" "); + } + destinationAddress.append(delivery.getCountry().getIsoCode()); + + + try { + GeocodingResult[] originAdressResult = GeocodingApi.geocode(context, + originAddress.toString()).await(); + + GeocodingResult[] destinationAdressResult = GeocodingApi.geocode(context, + destinationAddress.toString()).await(); + + if(originAdressResult.length>0 && destinationAdressResult.length>0) { + LatLng originLatLng = originAdressResult[0].geometry.location; + LatLng destinationLatLng = destinationAdressResult[0].geometry.location; + + delivery.setLatitude(String.valueOf(destinationLatLng.lat)); + delivery.setLongitude(String.valueOf(destinationLatLng.lng)); + + //keep latlng for further usage in order to display the map + + + DistanceMatrix distanceRequest = DistanceMatrixApi.newRequest(context) + .origins(new LatLng(originLatLng.lat, originLatLng.lng)) + + .destinations(new LatLng(destinationLatLng.lat, destinationLatLng.lng)) + .awaitIgnoreError(); + + + if(distanceRequest!=null) { + DistanceMatrixRow distanceMax = distanceRequest.rows[0]; + Distance distance = distanceMax.elements[0].distance; + quote.getQuoteInformations().put(Constants.DISTANCE_KEY, 0.001 * distance.inMeters); + } else { + LOGGER.error("Expected distance inner google api to return DistanceMatrix, it returned null. API key might not be working for this request"); + } + + } + + } catch (Exception e) { + LOGGER.error("Exception while calculating the shipping distance",e); + } + + } + + + + + + public String getModuleCode() { + return MODULE_CODE; + } + + + + + + + + + + + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/ShippingInputParameters.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/ShippingInputParameters.java new file mode 100755 index 0000000000..58c5000930 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/ShippingInputParameters.java @@ -0,0 +1,84 @@ +package com.salesmanager.core.business.modules.integration.shipping.impl; + +public class ShippingInputParameters { + + private String moduleName; + private long weight; + private long volume; + private String country; + private String province; + private long distance; + private long size; + private int price;//integer should be rounded from BigBecimal + private String priceQuote; + + public String getModuleName() { + return moduleName; + } + public void setModuleName(String moduleName) { + this.moduleName = moduleName; + } + public long getWeight() { + return weight; + } + public void setWeight(long weight) { + this.weight = weight; + } + public long getVolume() { + return volume; + } + public void setVolume(long volume) { + this.volume = volume; + } + public String getCountry() { + return country; + } + public void setCountry(String country) { + this.country = country; + } + public String getProvince() { + return province; + } + public void setProvince(String province) { + this.province = province; + } + public long getDistance() { + return distance; + } + public void setDistance(long distance) { + this.distance = distance; + } + public String getPriceQuote() { + return priceQuote; + } + public void setPriceQuote(String priceQuote) { + this.priceQuote = priceQuote; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(" weight : ").append(this.getWeight()); + sb.append(" volume : ").append(this.getVolume()) + .append(" size : ").append(this.getSize()) + .append(" distance : ").append(this.getDistance()) + .append(" province : ").append(this.getProvince()) + .append(" price : ").append(this.getPrice()) + .append(" country : ").append(this.getCountry()); + return sb.toString(); + } + + public long getSize() { + return size; + } + public void setSize(long size) { + this.size = size; + } + public int getPrice() { + return price; + } + public void setPrice(int price) { + this.price = price; + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/StorePickupShippingQuote.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/StorePickupShippingQuote.java new file mode 100755 index 0000000000..4435335a78 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/StorePickupShippingQuote.java @@ -0,0 +1,184 @@ +package com.salesmanager.core.business.modules.integration.shipping.impl; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.services.system.MerchantConfigurationService; +import com.salesmanager.core.business.utils.ProductPriceUtils; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.shipping.PackageDetails; +import com.salesmanager.core.model.shipping.ShippingConfiguration; +import com.salesmanager.core.model.shipping.ShippingOption; +import com.salesmanager.core.model.shipping.ShippingOrigin; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.model.system.CustomIntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.modules.integration.IntegrationException; +import com.salesmanager.core.modules.integration.shipping.model.ShippingQuoteModule; +import com.salesmanager.core.modules.integration.shipping.model.ShippingQuotePrePostProcessModule; + + +/** + * Store pick up shipping module + * + * Requires a configuration of a message note to be printed to the client + * and a price for calculation (should be configured to 0) + * + * Calculates a ShippingQuote with a price set to the price configured + * @author carlsamson + * + */ +public class StorePickupShippingQuote implements ShippingQuoteModule, ShippingQuotePrePostProcessModule { + + + public final static String MODULE_CODE = "storePickUp"; + + @Inject + private MerchantConfigurationService merchantConfigurationService; + + @Inject + private ProductPriceUtils productPriceUtils; + + + @Override + public void validateModuleConfiguration( + IntegrationConfiguration integrationConfiguration, + MerchantStore store) throws IntegrationException { + + + + + List errorFields = null; + + //validate integrationKeys['account'] + Map keys = integrationConfiguration.getIntegrationKeys(); + //if(keys==null || StringUtils.isBlank(keys.get("price"))) { + if(keys==null) { + errorFields = new ArrayList(); + errorFields.add("price"); + } else { + //validate it can be parsed to BigDecimal + try { + BigDecimal price = new BigDecimal(keys.get("price")); + } catch(Exception e) { + errorFields = new ArrayList(); + errorFields.add("price"); + } + } + + //if(keys==null || StringUtils.isBlank(keys.get("note"))) { + if(keys==null) { + errorFields = new ArrayList(); + errorFields.add("note"); + } + + + + if(errorFields!=null) { + IntegrationException ex = new IntegrationException(IntegrationException.ERROR_VALIDATION_SAVE); + ex.setErrorFields(errorFields); + throw ex; + + } + + } + + @Override + public List getShippingQuotes( + ShippingQuote shippingQuote, + List packages, BigDecimal orderTotal, + Delivery delivery, ShippingOrigin origin, MerchantStore store, + IntegrationConfiguration configuration, IntegrationModule module, + ShippingConfiguration shippingConfiguration, Locale locale) + throws IntegrationException { + + // TODO Auto-generated method stub + return null; + + } + + @Override + public CustomIntegrationConfiguration getCustomModuleConfiguration( + MerchantStore store) throws IntegrationException { + // TODO Auto-generated method stub + return null; + } + + @Override + public void prePostProcessShippingQuotes(ShippingQuote quote, + List packages, BigDecimal orderTotal, + Delivery delivery, ShippingOrigin origin, MerchantStore store, + IntegrationConfiguration globalShippingConfiguration, + IntegrationModule currentModule, + ShippingConfiguration shippingConfiguration, + List allModules, Locale locale) + throws IntegrationException { + + Validate.notNull(globalShippingConfiguration, "IntegrationConfiguration must not be null for StorePickUp"); + + + try { + + if(!globalShippingConfiguration.isActive()) + return; + + String region = null; + + String price = globalShippingConfiguration.getIntegrationKeys().get("price"); + + + if(delivery.getZone()!=null) { + region = delivery.getZone().getCode(); + } else { + region = delivery.getState(); + } + + ShippingOption shippingOption = new ShippingOption(); + shippingOption.setShippingModuleCode(MODULE_CODE); + shippingOption.setOptionCode(MODULE_CODE); + shippingOption.setOptionId(new StringBuilder().append(MODULE_CODE).append("_").append(region).toString()); + + shippingOption.setOptionPrice(productPriceUtils.getAmount(price)); + + shippingOption.setOptionPriceText(productPriceUtils.getStoreFormatedAmountWithCurrency(store, productPriceUtils.getAmount(price))); + + List options = quote.getShippingOptions(); + + if(options == null) { + options = new ArrayList(); + quote.setShippingOptions(options); + } + + options.add(shippingOption); + + if(quote.getSelectedShippingOption()==null) { + quote.setSelectedShippingOption(shippingOption); + } + + + } catch (Exception e) { + throw new IntegrationException(e); + } + + + + } + + @Override + public String getModuleCode() { + // TODO Auto-generated method stub + return MODULE_CODE; + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/UPSShippingQuote.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/UPSShippingQuote.java new file mode 100755 index 0000000000..66e34de092 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/UPSShippingQuote.java @@ -0,0 +1,692 @@ +package com.salesmanager.core.business.modules.integration.shipping.impl; + +import java.io.BufferedReader; +import java.io.Reader; +import java.io.StringReader; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.digester.Digester; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.apache.http.HttpEntity; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.salesmanager.core.business.utils.DataUtils; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.shipping.PackageDetails; +import com.salesmanager.core.model.shipping.ShippingConfiguration; +import com.salesmanager.core.model.shipping.ShippingOption; +import com.salesmanager.core.model.shipping.ShippingOrigin; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.model.system.CustomIntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.model.system.ModuleConfig; +import com.salesmanager.core.modules.integration.IntegrationException; +import com.salesmanager.core.modules.integration.shipping.model.ShippingQuoteModule; + + +/** + * Integrates with UPS online API + * @author casams1 + * + */ +public class UPSShippingQuote implements ShippingQuoteModule { + + private static final Logger LOGGER = LoggerFactory.getLogger(UPSShippingQuote.class); + + + @Override + public void validateModuleConfiguration( + IntegrationConfiguration integrationConfiguration, + MerchantStore store) throws IntegrationException { + + + List errorFields = null; + + //validate integrationKeys['accessKey'] + Map keys = integrationConfiguration.getIntegrationKeys(); + if(keys==null || StringUtils.isBlank(keys.get("accessKey"))) { + errorFields = new ArrayList(); + errorFields.add("accessKey"); + } + + if(keys==null || StringUtils.isBlank(keys.get("userId"))) { + errorFields = new ArrayList(); + errorFields.add("userId"); + } + + if(keys==null || StringUtils.isBlank(keys.get("password"))) { + errorFields = new ArrayList(); + errorFields.add("password"); + } + + //validate at least one integrationOptions['packages'] + Map> options = integrationConfiguration.getIntegrationOptions(); + if(options==null) { + errorFields = new ArrayList(); + errorFields.add("packages"); + } + + List packages = options.get("packages"); + if(packages==null || packages.size()==0) { + if(errorFields==null) { + errorFields = new ArrayList(); + } + errorFields.add("packages"); + } + +/* List services = options.get("services"); + if(services==null || services.size()==0) { + if(errorFields==null) { + errorFields = new ArrayList(); + } + errorFields.add("services"); + } + + if(services!=null && services.size()>3) { + if(errorFields==null) { + errorFields = new ArrayList(); + } + errorFields.add("services"); + }*/ + + if(errorFields!=null) { + IntegrationException ex = new IntegrationException(IntegrationException.ERROR_VALIDATION_SAVE); + ex.setErrorFields(errorFields); + throw ex; + + } + + + + } + + @Override + public List getShippingQuotes( + ShippingQuote shippingQuote, + List packages, BigDecimal orderTotal, + Delivery delivery, ShippingOrigin origin, MerchantStore store, + IntegrationConfiguration configuration, IntegrationModule module, + ShippingConfiguration shippingConfiguration, Locale locale) + throws IntegrationException { + + Validate.notNull(configuration, "IntegrationConfiguration must not be null for USPS shipping module"); + + + if(StringUtils.isBlank(delivery.getPostalCode())) { + return null; + } + + BigDecimal total = orderTotal; + + if (packages == null) { + return null; + } + + List options = null; + + // only applies to Canada and US + Country country = delivery.getCountry(); + + + + if(!(country.getIsoCode().equals("US") || country.getIsoCode().equals("CA"))) { + return null; + //throw new IntegrationException("UPS Not configured for shipping in country " + country.getIsoCode()); + } + + // supports en and fr + String language = locale.getLanguage(); + if (!language.equals(Locale.FRENCH.getLanguage()) + && !language.equals(Locale.ENGLISH.getLanguage())) { + language = Locale.ENGLISH.getLanguage(); + } + + String pack = configuration.getIntegrationOptions().get("packages").get(0); + Map keys = configuration.getIntegrationKeys(); + + String accessKey = keys.get("accessKey"); + String userId = keys.get("userId"); + String password = keys.get("password"); + + + String host = null; + String protocol = null; + String port = null; + String url = null; + + StringBuilder xmlbuffer = new StringBuilder(); + HttpPost httppost = null; + BufferedReader reader = null; + + try { + String env = configuration.getEnvironment(); + + Set regions = module.getRegionsSet(); + if(!regions.contains(store.getCountry().getIsoCode())) { + throw new IntegrationException("Can't use the service for store country code "); + } + + Map moduleConfigsMap = module.getModuleConfigs(); + for(String key : moduleConfigsMap.keySet()) { + + ModuleConfig moduleConfig = moduleConfigsMap.get(key); + if(moduleConfig.getEnv().equals(env)) { + host = moduleConfig.getHost(); + protocol = moduleConfig.getScheme(); + port = moduleConfig.getPort(); + url = moduleConfig.getUri(); + } + } + + + StringBuilder xmlreqbuffer = new StringBuilder(); + xmlreqbuffer.append(""); + xmlreqbuffer.append(""); + xmlreqbuffer.append(""); + xmlreqbuffer.append(accessKey); + xmlreqbuffer.append(""); + xmlreqbuffer.append(""); + xmlreqbuffer.append(userId); + xmlreqbuffer.append(""); + xmlreqbuffer.append(""); + xmlreqbuffer.append(password); + xmlreqbuffer.append(""); + xmlreqbuffer.append(""); + + String xmlhead = xmlreqbuffer.toString(); + + + String weightCode = store.getWeightunitcode(); + String measureCode = store.getSeizeunitcode(); + + if (weightCode.equals("KG")) { + weightCode = "KGS"; + } else { + weightCode = "LBS"; + } + + String xml = "Shopizer1.0001RateShop"; + StringBuilder xmldatabuffer = new StringBuilder(); + + /** + * + * + *
    + * QC + * CA + *
    + * + *
    Redwood Shores + * CA + * US + *
    + * + * 21 + * LBS + * 1.1 + * + * CAD + * 100 + * + * + * + *
    + * + * 03 + *
    + * **/ + + /**Map countriesMap = (Map) RefCache.getAllcountriesmap(LanguageUtil + .getLanguageNumberCode(locale.getLanguage())); + Map zonesMap = (Map) RefCache.getAllZonesmap(LanguageUtil + .getLanguageNumberCode(locale.getLanguage())); + + Country storeCountry = (Country) countriesMap.get(store + .getCountry()); + + Country customerCountry = (Country) countriesMap.get(customer + .getCustomerCountryId()); + + int sZone = -1; + try { + sZone = Integer.parseInt(store.getZone()); + } catch (Exception e) { + // TODO: handle exception + } + + Zone storeZone = (Zone) zonesMap.get(sZone); + Zone customerZone = (Zone) zonesMap.get(customer + .getCustomerZoneId());**/ + + + + xmldatabuffer.append("03"); + // xmldatabuffer.append("Daily Pickup"); + xmldatabuffer.append(""); + xmldatabuffer.append("
    "); + xmldatabuffer.append(""); + xmldatabuffer.append(store.getStorecity()); + xmldatabuffer.append(""); + // if(!StringUtils.isBlank(store.getStorestateprovince())) { + if (store.getZone() != null) { + xmldatabuffer.append(""); + xmldatabuffer.append(store.getZone().getCode());// zone code + xmldatabuffer.append(""); + } + xmldatabuffer.append(""); + xmldatabuffer.append(store.getCountry().getIsoCode()); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(DataUtils + .trimPostalCode(store.getStorepostalcode())); + xmldatabuffer.append("
    "); + + // ship to + xmldatabuffer.append(""); + xmldatabuffer.append("
    "); + xmldatabuffer.append(""); + xmldatabuffer.append(delivery.getCity()); + xmldatabuffer.append(""); + // if(!StringUtils.isBlank(customer.getCustomerState())) { + if (delivery.getZone() != null) { + xmldatabuffer.append(""); + xmldatabuffer.append(delivery.getZone().getCode());// zone code + xmldatabuffer.append(""); + } + xmldatabuffer.append(""); + xmldatabuffer.append(delivery.getCountry().getIsoCode()); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(DataUtils + .trimPostalCode(delivery.getPostalCode())); + xmldatabuffer.append("
    "); + // xmldatabuffer.append("11");//TODO service codes (next day ...) + + + for(PackageDetails packageDetail : packages){ + + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(pack); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + + // weight + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(weightCode); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(new BigDecimal(packageDetail.getShippingWeight()) + .setScale(1, BigDecimal.ROUND_HALF_UP)); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + + // dimension + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(measureCode); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(new BigDecimal(packageDetail.getShippingLength()) + .setScale(2, BigDecimal.ROUND_HALF_UP)); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(new BigDecimal(packageDetail.getShippingWidth()) + .setScale(2, BigDecimal.ROUND_HALF_UP)); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(new BigDecimal(packageDetail.getShippingHeight()) + .setScale(2, BigDecimal.ROUND_HALF_UP)); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + + } + + xmldatabuffer.append("
    "); + xmldatabuffer.append(""); + + xmlbuffer.append(xmlhead).append(xml).append( + xmldatabuffer.toString()); + + + + LOGGER.debug("UPS QUOTE REQUEST " + xmlbuffer.toString()); + + + try(CloseableHttpClient httpclient = HttpClients.createDefault()) { + //HttpClient client = new HttpClient(); + httppost = new HttpPost(protocol + "://" + host + ":" + port + + url); + StringEntity entity = new StringEntity(xmlbuffer.toString(),ContentType.APPLICATION_ATOM_XML); + //RequestEntity entity = new StringRequestEntity( + // xmlbuffer.toString(), "text/plain", "UTF-8"); + httppost.setEntity(entity); + // Create a custom response handler + ResponseHandler responseHandler = response -> { + int status = response.getStatusLine().getStatusCode(); + if (status >= 200 && status < 300) { + HttpEntity entity1 = response.getEntity(); + return entity1 != null ? EntityUtils.toString(entity1) : null; + } else { + LOGGER.error("Communication Error with ups quote " + status); + throw new ClientProtocolException("UPS quote communication error " + status); + } + }; + String data = httpclient.execute(httppost, responseHandler); + + //int result = response.getStatusLine().getStatusCode(); + //int result = client.executeMethod(httppost); +/* if (result != 200) { + LOGGER.error("Communication Error with ups quote " + result + " " + + protocol + "://" + host + ":" + port + url); + throw new Exception("UPS quote communication error " + result); + }*/ + + LOGGER.debug("ups quote response " + data); + + UPSParsedElements parsed = new UPSParsedElements(); + + Digester digester = new Digester(); + digester.push(parsed); + digester.addCallMethod( + "RatingServiceSelectionResponse/Response/Error", + "setErrorCode", 0); + digester.addCallMethod( + "RatingServiceSelectionResponse/Response/ErrorDescriprion", + "setError", 0); + digester + .addCallMethod( + "RatingServiceSelectionResponse/Response/ResponseStatusCode", + "setStatusCode", 0); + digester + .addCallMethod( + "RatingServiceSelectionResponse/Response/ResponseStatusDescription", + "setStatusMessage", 0); + digester + .addCallMethod( + "RatingServiceSelectionResponse/Response/Error/ErrorDescription", + "setError", 0); + + digester.addObjectCreate( + "RatingServiceSelectionResponse/RatedShipment", + ShippingOption.class); + // digester.addSetProperties( + // "RatingServiceSelectionResponse/RatedShipment", "sequence", + // "optionId" ); + digester + .addCallMethod( + "RatingServiceSelectionResponse/RatedShipment/Service/Code", + "setOptionId", 0); + digester + .addCallMethod( + "RatingServiceSelectionResponse/RatedShipment/TotalCharges/MonetaryValue", + "setOptionPriceText", 0); + //digester + // .addCallMethod( + // "RatingServiceSelectionResponse/RatedShipment/TotalCharges/CurrencyCode", + // "setCurrency", 0); + digester + .addCallMethod( + "RatingServiceSelectionResponse/RatedShipment/Service/Code", + "setOptionCode", 0); + digester + .addCallMethod( + "RatingServiceSelectionResponse/RatedShipment/GuaranteedDaysToDelivery", + "setEstimatedNumberOfDays", 0); + digester.addSetNext("RatingServiceSelectionResponse/RatedShipment", + "addOption"); + + // SalesManager + // Data1.00FailureHard10002The + // XML document is well formed but the document is not + // validAddressValidationRequest + + Reader xmlreader = new StringReader(data); + + digester.parse(xmlreader); + + if (!StringUtils.isBlank(parsed.getErrorCode())) { + + LOGGER.error("Can't process UPS statusCode=" + + parsed.getErrorCode() + " message= " + + parsed.getError()); + throw new IntegrationException(parsed.getError()); + } + if (!StringUtils.isBlank(parsed.getStatusCode()) + && !parsed.getStatusCode().equals("1")) { + + throw new IntegrationException(parsed.getError()); + } + + if (parsed.getOptions() == null || parsed.getOptions().size() == 0) { + + throw new IntegrationException("No shipping options available for the configuration"); + } + + /*String carrier = getShippingMethodDescription(locale); + // cost is in CAD, need to do conversion + + boolean requiresCurrencyConversion = false; String storeCurrency + = store.getCurrency(); + if(!storeCurrency.equals(Constants.CURRENCY_CODE_CAD)) { + requiresCurrencyConversion = true; } + + LabelUtil labelUtil = LabelUtil.getInstance(); + Map serviceMap = com.salesmanager.core.util.ShippingUtil + .buildServiceMap("upsxml", locale); + + *//** Details on whit RT quote information to display **//* + MerchantConfiguration rtdetails = config + .getMerchantConfiguration(ShippingConstants.MODULE_SHIPPING_DISPLAY_REALTIME_QUOTES); + int displayQuoteDeliveryTime = ShippingConstants.NO_DISPLAY_RT_QUOTE_TIME; + if (rtdetails != null) { + + if (!StringUtils.isBlank(rtdetails.getConfigurationValue1())) {// display + // or + // not + // quotes + try { + displayQuoteDeliveryTime = Integer.parseInt(rtdetails + .getConfigurationValue1()); + + } catch (Exception e) { + log.error("Display quote is not an integer value [" + + rtdetails.getConfigurationValue1() + "]"); + } + } + }*/ + + List shippingOptions = parsed.getOptions(); + if(shippingOptions!=null) { + Map details = module.getDetails(); + for(ShippingOption option : shippingOptions) { + String name = details.get(option.getOptionCode()); + option.setOptionName(name); + if(option.getOptionPrice()==null) { + String priceText = option.getOptionPriceText(); + if(StringUtils.isBlank(priceText)) { + throw new IntegrationException("Price text is null for option " + name); + } + try { + BigDecimal price = new BigDecimal(priceText); + option.setOptionPrice(price); + } catch(Exception e) { + throw new IntegrationException("Can't convert to numeric price " + priceText); + } + } + } + } +/* if (options != null) { + + Map selectedintlservices = (Map) config + .getConfiguration("service-global-upsxml"); + + Iterator i = options.iterator(); + while (i.hasNext()) { + ShippingOption option = (ShippingOption) i.next(); + // option.setCurrency(store.getCurrency()); + StringBuffer description = new StringBuffer(); + + String code = option.getOptionCode(); + option.setOptionCode(code); + // get description + String label = (String) serviceMap.get(code); + if (label == null) { + log + .warn("UPSXML cannot find description for service code " + + code); + } + + option.setOptionName(label); + + description.append(option.getOptionName()); + if (displayQuoteDeliveryTime == ShippingConstants.DISPLAY_RT_QUOTE_TIME) { + if (!StringUtils.isBlank(option + .getEstimatedNumberOfDays())) { + description.append(" (").append( + option.getEstimatedNumberOfDays()).append( + " ").append( + labelUtil.getText(locale, + "label.generic.days.lowercase")) + .append(")"); + } + } + option.setDescription(description.toString()); + + // get currency + if (!option.getCurrency().equals(store.getCurrency())) { + option.setOptionPrice(CurrencyUtil.convertToCurrency( + option.getOptionPrice(), option.getCurrency(), + store.getCurrency())); + } + + if (!selectedintlservices.containsKey(option + .getOptionCode())) { + if (returnColl == null) { + returnColl = new ArrayList(); + } + returnColl.add(option); + // options.remove(option); + } + + } + + if (options.size() == 0) { + LogMerchantUtil + .log( + store.getMerchantId(), + " none of the service code returned by UPS [" + + selectedintlservices + .keySet() + .toArray( + new String[selectedintlservices + .size()]) + + "] for this shipping is in your selection list"); + } + }*/ + + + + return shippingOptions; + } + } catch (Exception e1) { + LOGGER.error("UPS quote error",e1); + throw new IntegrationException(e1); + } finally { + if (reader != null) { + try { + reader.close(); + } catch (Exception ignore) { + } + } + + if (httppost != null) { + httppost.releaseConnection(); + } + } +} + + + @Override + public CustomIntegrationConfiguration getCustomModuleConfiguration( + MerchantStore store) throws IntegrationException { + //nothing to do + return null; + }} + + +class UPSParsedElements { + + private String statusCode; + private String statusMessage; + private String error = ""; + private String errorCode = ""; + private List options = new ArrayList(); + + public void addOption(ShippingOption option) { + options.add(option); + } + + public List getOptions() { + return options; + } + + public String getStatusCode() { + return statusCode; + } + + public void setStatusCode(String statusCode) { + this.statusCode = statusCode; + } + + public String getStatusMessage() { + return statusMessage; + } + + public void setStatusMessage(String statusMessage) { + this.statusMessage = statusMessage; + } + + public String getError() { + return error; + } + + public void setError(String error) { + this.error = error; + } + + public String getErrorCode() { + return errorCode; + } + + public void setErrorCode(String errorCode) { + this.errorCode = errorCode; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/USPSShippingQuote.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/USPSShippingQuote.java new file mode 100755 index 0000000000..3ebd741c27 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/integration/shipping/impl/USPSShippingQuote.java @@ -0,0 +1,744 @@ +package com.salesmanager.core.business.modules.integration.shipping.impl; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.commons.digester.Digester; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.utils.DataUtils; +import com.salesmanager.core.business.utils.ProductPriceUtils; +import com.salesmanager.core.constants.MeasureUnit; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shipping.PackageDetails; +import com.salesmanager.core.model.shipping.ShippingConfiguration; +import com.salesmanager.core.model.shipping.ShippingOption; +import com.salesmanager.core.model.shipping.ShippingOrigin; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.model.system.CustomIntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.model.system.ModuleConfig; +import com.salesmanager.core.modules.integration.IntegrationException; +import com.salesmanager.core.modules.integration.shipping.model.ShippingQuoteModule; + + +/** + * Integrates with USPS online API + * @author casams1 + * + */ +public class USPSShippingQuote implements ShippingQuoteModule { + + private static final Logger LOGGER = LoggerFactory.getLogger(USPSShippingQuote.class); + + + @Inject + private ProductPriceUtils productPriceUtils; + + @Inject + private CountryService countryService; + + + @Override + public void validateModuleConfiguration( + IntegrationConfiguration integrationConfiguration, + MerchantStore store) throws IntegrationException { + + + List errorFields = null; + + //validate integrationKeys['account'] + Map keys = integrationConfiguration.getIntegrationKeys(); + if(keys==null || StringUtils.isBlank(keys.get("account"))) { + errorFields = new ArrayList(); + errorFields.add("identifier"); + } + + //validate at least one integrationOptions['packages'] + Map> options = integrationConfiguration.getIntegrationOptions(); + if(options==null) { + errorFields = new ArrayList(); + errorFields.add("identifier"); + } + + List packages = options.get("packages"); + if(packages==null || packages.size()==0) { + if(errorFields==null) { + errorFields = new ArrayList(); + } + errorFields.add("packages"); + } + +/* List services = options.get("services"); + if(services==null || services.size()==0) { + if(errorFields==null) { + errorFields = new ArrayList(); + } + errorFields.add("services"); + } + + if(services!=null && services.size()>3) { + if(errorFields==null) { + errorFields = new ArrayList(); + } + errorFields.add("services"); + }*/ + + if(errorFields!=null) { + IntegrationException ex = new IntegrationException(IntegrationException.ERROR_VALIDATION_SAVE); + ex.setErrorFields(errorFields); + throw ex; + + } + + + + } + + @Override + public List getShippingQuotes( + ShippingQuote shippingQuote, + List packages, BigDecimal orderTotal, + Delivery delivery, ShippingOrigin origin, MerchantStore store, + IntegrationConfiguration configuration, IntegrationModule module, + ShippingConfiguration shippingConfiguration, Locale locale) + throws IntegrationException { + + + + if (packages == null) { + return null; + } + + if(StringUtils.isBlank(delivery.getPostalCode())) { + return null; + } + + + + // only applies to Canada and US +/* Country country = delivery.getCountry(); + if(!country.getIsoCode().equals("US") || !country.getIsoCode().equals("US")){ + throw new IntegrationException("USPS Not configured for shipping in country " + country.getIsoCode()); + }*/ + + + + // supports en and fr + String language = locale.getLanguage(); + if (!language.equals(Locale.FRENCH.getLanguage()) + && !language.equals(Locale.ENGLISH.getLanguage())) { + language = Locale.ENGLISH.getLanguage(); + } + + + // if store is not CAD /** maintained in the currency **/ +/* if (!store.getCurrency().equals(Constants.CURRENCY_CODE_CAD)) { + total = CurrencyUtil.convertToCurrency(total, store.getCurrency(), + Constants.CURRENCY_CODE_CAD); + }*/ + + Language lang = store.getDefaultLanguage(); + + + + HttpGet httpget = null; + Reader xmlreader = null; + String pack = configuration.getIntegrationOptions().get("packages").get(0); + + try { + + Map countries = countryService.getCountriesMap(lang); + + Country destination = countries.get(delivery.getCountry().getIsoCode()); + + + + Map keys = configuration.getIntegrationKeys(); + if(keys==null || StringUtils.isBlank(keys.get("account"))) { + return null;//TODO can we return null + } + + + String host = null; + String protocol = null; + String port = null; + String url = null; + + + + //against which environment are we using the service + String env = configuration.getEnvironment(); + + //must be US + if(!store.getCountry().getIsoCode().equals("US")) { + throw new IntegrationException("Can't use the service for store country code "); + } + + Map moduleConfigsMap = module.getModuleConfigs(); + for(String key : moduleConfigsMap.keySet()) { + + ModuleConfig moduleConfig = moduleConfigsMap.get(key); + if(moduleConfig.getEnv().equals(env)) { + host = moduleConfig.getHost(); + protocol = moduleConfig.getScheme(); + port = moduleConfig.getPort(); + url = moduleConfig.getUri(); + } + } + + + StringBuilder xmlheader = new StringBuilder(); + if(store.getCountry().getIsoCode().equals(delivery.getCountry().getIsoCode())) { + xmlheader.append(""); + } else { + xmlheader.append(""); + } + + + + StringBuilder xmldatabuffer = new StringBuilder(); + + + double totalW = 0; + double totalH = 0; + double totalL = 0; + double totalG = 0; + double totalP = 0; + + for (PackageDetails detail : packages) { + + + // need size in inch + double w = DataUtils.getMeasure(detail.getShippingWidth(), + store, MeasureUnit.IN.name()); + double h = DataUtils.getMeasure(detail.getShippingHeight(), + store, MeasureUnit.IN.name()); + double l = DataUtils.getMeasure(detail.getShippingLength(), + store, MeasureUnit.IN.name()); + + totalW = totalW + w; + totalH = totalH + h; + totalL = totalL + l; + + // Girth = Length + (Width x 2) + (Height x 2) + double girth = l + (w * 2) + (h * 2); + + totalG = totalG + girth; + + // need weight in pounds + double p = DataUtils.getWeight(detail.getShippingWeight(), store, MeasureUnit.LB.name()); + + totalP = totalP + p; + + } + +/* BigDecimal convertedOrderTotal = CurrencyUtil.convertToCurrency( + orderTotal, store.getCurrency(), + Constants.CURRENCY_CODE_USD);*/ + + // calculate total shipping volume + + // ship date is 3 days from here + + Calendar c = Calendar.getInstance(); + c.setTime(new Date()); + c.add(Calendar.DATE, 3); + Date newDate = c.getTime(); + + SimpleDateFormat format = new SimpleDateFormat(Constants.DEFAULT_DATE_FORMAT); + String shipDate = format.format(newDate); + + + + int i = 1; + + // need pounds and ounces + int pounds = (int) totalP; + String ouncesString = String.valueOf(totalP - pounds); + int ouncesIndex = ouncesString.indexOf("."); + String ounces = "00"; + if (ouncesIndex > -1) { + ounces = ouncesString.substring(ouncesIndex + 1); + } + + String size = "REGULAR"; + + if (totalL + totalG <= 64) { + size = "REGULAR"; + } else if (totalL + totalG <= 108) { + size = "LARGE"; + } else { + size = "OVERSIZE"; + } + + /** + * Domestic ALL + * 90210 + * 96698 8 + * 32 REGULAR + * true + * + * //MAXWEIGHT=70 lbs + * + * + * //domestic container default=VARIABLE whiteSpace=collapse + * enumeration=VARIABLE enumeration=FLAT RATE BOX enumeration=FLAT + * RATE ENVELOPE enumeration=LG FLAT RATE BOX + * enumeration=RECTANGULAR enumeration=NONRECTANGULAR + * + * //INTL enumeration=Package enumeration=Postcards or aerogrammes + * enumeration=Matter for the blind enumeration=Envelope + * + * Size May be left blank in situations that do not Size. Defined as + * follows: REGULAR: package plus girth is 84 inches or less; LARGE: + * package length plus girth measure more than 84 inches not more + * than 108 inches; OVERSIZE: package length plus girth is more than + * 108 but not 130 inches. For example: REGULAR + * + * International true + * Envelope Canada + * 0 0 0 + * 250 + * + * 4 3 + * Package 46 + * 14 15 N + * N + * 250 Japan + * + */ + + xmldatabuffer.append(""); + + + if(store.getCountry().getIsoCode().equals(delivery.getCountry().getIsoCode())) { + + xmldatabuffer.append(""); + xmldatabuffer.append("ALL"); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(DataUtils + .trimPostalCode(store.getStorepostalcode())); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(DataUtils + .trimPostalCode(delivery.getPostalCode())); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(pounds); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(ounces); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(pack); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(size); + xmldatabuffer.append(""); + xmldatabuffer.append("true");//TODO must be changed if not machinable + xmldatabuffer.append(""); + xmldatabuffer.append(shipDate); + xmldatabuffer.append(""); + } else { + // if international + xmldatabuffer.append(""); + xmldatabuffer.append(pounds); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(ounces); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(pack); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(productPriceUtils.getAdminFormatedAmount(store, orderTotal)); + xmldatabuffer.append(""); + xmldatabuffer.append(""); + xmldatabuffer.append(destination.getName()); + xmldatabuffer.append(""); + } + + // if international & CXG + /* + * xmldatabuffer.append(""); xmldatabuffer.append(""); + * xmldatabuffer.append(""); xmldatabuffer.append(""); + * xmldatabuffer.append(""); xmldatabuffer.append(""); + * xmldatabuffer.append(""); + * xmldatabuffer.append(""); xmldatabuffer.append(""); + * xmldatabuffer.append(""); + * xmldatabuffer.append(""); xmldatabuffer.append(""); + * xmldatabuffer.append(""); + * xmldatabuffer.append(""); xmldatabuffer.append(""); + * xmldatabuffer.append(""); + * xmldatabuffer.append(""); + */ + + /* + * xmldatabuffer.append(""); xmldatabuffer.append(totalW); + * xmldatabuffer.append(""); + * xmldatabuffer.append(""); xmldatabuffer.append(totalL); + * xmldatabuffer.append(""); + * xmldatabuffer.append(""); xmldatabuffer.append(totalH); + * xmldatabuffer.append(""); + * xmldatabuffer.append(""); xmldatabuffer.append(totalG); + * xmldatabuffer.append(""); + */ + + xmldatabuffer.append(""); + + String xmlfooter = ""; + if(!store.getCountry().getIsoCode().equals(delivery.getCountry().getIsoCode())) { + xmlfooter = ""; + } + + StringBuilder xmlbuffer = new StringBuilder().append(xmlheader.toString()).append( + xmldatabuffer.toString()).append(xmlfooter); + + LOGGER.debug("USPS QUOTE REQUEST " + xmlbuffer.toString()); + //HttpClient client = new HttpClient(); + try(CloseableHttpClient httpclient = HttpClients.createDefault()) { + @SuppressWarnings("deprecation") + String encoded = java.net.URLEncoder.encode(xmlbuffer.toString()); + + String completeUri = url + "?API=RateV3&XML=" + encoded; + if(!store.getCountry().getIsoCode().equals(delivery.getCountry().getIsoCode())) { + completeUri = url + "?API=IntlRate&XML=" + encoded; + } + + // ?API=RateV3 + + httpget = new HttpGet(protocol + "://" + host + ":" + port + + completeUri); + // RequestEntity entity = new + // StringRequestEntity(xmlbuffer.toString(),"text/plain","UTF-8"); + // httpget.setRequestEntity(entity); + + ResponseHandler responseHandler = response -> { + int status = response.getStatusLine().getStatusCode(); + if (status >= 200 && status < 300) { + HttpEntity entity = response.getEntity(); + return entity != null ? EntityUtils.toString(entity) : null; + } else { + LOGGER.error("Communication Error with ups quote " + status); + throw new ClientProtocolException("UPS quote communication error " + status); + } + }; + + String data = httpclient.execute(httpget, responseHandler); +/* int result = client.executeMethod(httpget); + if (result != 200) { + LOGGER.error("Communication Error with usps quote " + result + " " + + protocol + "://" + host + ":" + port + url); + throw new Exception("USPS quote communication error " + result); + }*/ + //data = httpget.getResponseBodyAsString(); + LOGGER.debug("usps quote response " + data); + + USPSParsedElements parsed = new USPSParsedElements(); + + /** + * + * 44106 + * 20770 + */ + + Digester digester = new Digester(); + digester.push(parsed); + + if(store.getCountry().getIsoCode().equals(delivery.getCountry().getIsoCode())) { + + digester.addCallMethod("Error/Description", + "setError", 0); + digester.addCallMethod("RateV3Response/Package/Error/Description", + "setError", 0); + digester + .addObjectCreate( + "RateV3Response/Package/Postage", + ShippingOption.class); + digester.addSetProperties("RateV3Response/Package/Postage", + "CLASSID", "optionId"); + digester.addCallMethod( + "RateV3Response/Package/Postage/MailService", + "setOptionName", 0); + digester.addCallMethod( + "RateV3Response/Package/Postage/MailService", + "setOptionCode", 0); + digester.addCallMethod("RateV3Response/Package/Postage/Rate", + "setOptionPriceText", 0); + //digester + // .addCallMethod( + // "RateV3Response/Package/Postage/Commitment/CommitmentDate", + // "estimatedNumberOfDays", 0); + digester.addSetNext("RateV3Response/Package/Postage", + "addOption"); + + } else { + + digester.addCallMethod("Error/Description", + "setError", 0); + digester.addCallMethod("IntlRateResponse/Package/Error/Description", + "setError", 0); + digester + .addObjectCreate( + "IntlRateResponse/Package/Service", + ShippingOption.class); + digester.addSetProperties("IntlRateResponse/Package/Service", + "ID", "optionId"); + digester.addCallMethod( + "IntlRateResponse/Package/Service/SvcDescription", + "setOptionName", 0); + digester.addCallMethod( + "IntlRateResponse/Package/Service/SvcDescription", + "setOptionCode", 0); + digester.addCallMethod( + "IntlRateResponse/Package/Service/Postage", + "setOptionPriceText", 0); + //digester.addCallMethod( + // "IntlRateResponse/Package/Service/SvcCommitments", + // "setEstimatedNumberOfDays", 0); + digester.addSetNext("IntlRateResponse/Package/Service", + "addOption"); + + } + + // SalesManager + // Data1.00FailureHard10002The + // XML document is well formed but the document is not + // validAddressValidationRequest + + + // + //-2147218046 + //IntlPostage;clsIntlPostage.GetCountryAndRestirctedServiceId;clsIntlPostage.CalcAllPostageDimensionsXML;IntlRate.ProcessRequest + //Invalid Country Name1000440 + + + xmlreader = new StringReader(data); + digester.parse(xmlreader); + + if (!StringUtils.isBlank(parsed.getError())) { + LOGGER.error("Can't process USPS message= " + + parsed.getError()); + throw new IntegrationException(parsed.getError()); + } + if (!StringUtils.isBlank(parsed.getStatusCode()) + && !parsed.getStatusCode().equals("1")) { + LOGGER.error("Can't process USPS statusCode=" + + parsed.getStatusCode() + " message= " + + parsed.getError()); + throw new IntegrationException(parsed.getError()); + } + + if (parsed.getOptions() == null || parsed.getOptions().size() == 0) { + LOGGER.warn("No options returned from USPS"); + throw new IntegrationException(parsed.getError()); + } + + + +/* String carrier = getShippingMethodDescription(locale); + // cost is in USD, need to do conversion + + MerchantConfiguration rtdetails = config + .getMerchantConfiguration(ShippingConstants.MODULE_SHIPPING_DISPLAY_REALTIME_QUOTES); + int displayQuoteDeliveryTime = ShippingConstants.NO_DISPLAY_RT_QUOTE_TIME; + if (rtdetails != null) { + + if (!StringUtils.isBlank(rtdetails.getConfigurationValue1())) {// display + // or + // not + // quotes + try { + displayQuoteDeliveryTime = Integer.parseInt(rtdetails + .getConfigurationValue1()); + + } catch (Exception e) { + log.error("Display quote is not an integer value [" + + rtdetails.getConfigurationValue1() + "]"); + } + } + } + + LabelUtil labelUtil = LabelUtil.getInstance();*/ + // Map serviceMap = + // com.salesmanager.core.util.ShippingUtil.buildServiceMap("usps",locale); + + @SuppressWarnings("unchecked") + List shippingOptions = parsed.getOptions(); + +/* List returnOptions = null; + + if (shippingOptions != null && shippingOptions.size() > 0) { + + returnOptions = new ArrayList(); + // Map selectedintlservices = + // (Map)config.getConfiguration("service-global-usps"); + // need to create a Map of LABEL - LABLEL + // Iterator servicesIterator = + // selectedintlservices.keySet().iterator(); + // Map services = new HashMap(); + + // ResourceBundle bundle = ResourceBundle.getBundle("usps", + // locale); + + // while(servicesIterator.hasNext()) { + // String key = (String)servicesIterator.next(); + // String value = + // bundle.getString("shipping.quote.services.label." + key); + // services.put(value, key); + // } + + for(ShippingOption option : shippingOptions) { + + StringBuilder description = new StringBuilder(); + description.append(option.getOptionName()); + //if (displayQuoteDeliveryTime == ShippingConstants.DISPLAY_RT_QUOTE_TIME) { + if (shippingConfiguration.getShippingDescription()==ShippingDescription.LONG_DESCRIPTION) { + if (option.getEstimatedNumberOfDays()>0) { + description.append(" (").append( + option.getEstimatedNumberOfDays()).append( + " ").append( + " d") + .append(")"); + } + } + option.setDescription(description.toString()); + + // get currency + if (!option.getCurrency().equals(store.getCurrency())) { + option.setOptionPrice(CurrencyUtil.convertToCurrency( + option.getOptionPrice(), option.getCurrency(), + store.getCurrency())); + } + + // if(!services.containsKey(option.getOptionCode())) { + // if(returnColl==null) { + // returnColl = new ArrayList(); + // } + // returnColl.add(option); + // } + returnOptions.add(option); + } + + // if(options.size()==0) { + // CommonService.logServiceMessage(store.getMerchantId(), + // " none of the service code returned by UPS [" + + // selectedintlservices.keySet().toArray(new + // String[selectedintlservices.size()]) + + // "] for this shipping is in your selection list"); + // } + + }*/ + + return shippingOptions; + } + + } catch (Exception e1) { + LOGGER.error("Error in USPS shipping quote ",e1); + throw new IntegrationException(e1); + } finally { + if (xmlreader != null) { + try { + xmlreader.close(); + } catch (Exception ignore) { + } + } + if (httpget != null) { + httpget.releaseConnection(); + } + } + + + } + + + + @Override + public CustomIntegrationConfiguration getCustomModuleConfiguration( + MerchantStore store) throws IntegrationException { + //nothing to do + return null; + } + +} + + +class USPSParsedElements { + + private String statusCode; + private String statusMessage; + private String error = ""; + private String errorCode = ""; + private List options = new ArrayList(); + + public void addOption(ShippingOption option) { + options.add(option); + } + + public List getOptions() { + return options; + } + + public String getStatusCode() { + return statusCode; + } + + public void setStatusCode(String statusCode) { + this.statusCode = statusCode; + } + + public String getStatusMessage() { + return statusMessage; + } + + public void setStatusMessage(String statusMessage) { + this.statusMessage = statusMessage; + } + + public String getError() { + return error; + } + + public void setError(String error) { + this.error = error; + } + + public String getErrorCode() { + return errorCode; + } + + public void setErrorCode(String errorCode) { + this.errorCode = errorCode; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/order/InvoiceModule.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/order/InvoiceModule.java new file mode 100755 index 0000000000..c737fc34be --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/order/InvoiceModule.java @@ -0,0 +1,14 @@ +package com.salesmanager.core.business.modules.order; + +import java.io.ByteArrayOutputStream; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.reference.language.Language; + + +public interface InvoiceModule { + + ByteArrayOutputStream createInvoice(MerchantStore store, Order order, Language language) throws Exception; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/order/ODSInvoiceModule.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/order/ODSInvoiceModule.java new file mode 100755 index 0000000000..5440d03462 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/order/ODSInvoiceModule.java @@ -0,0 +1,387 @@ +package com.salesmanager.core.business.modules.order; + +import java.io.ByteArrayOutputStream; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.zone.ZoneService; +import com.salesmanager.core.business.utils.ProductPriceUtils; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.reference.language.Language; + + + + + +public class ODSInvoiceModule implements InvoiceModule { + + private final static String INVOICE_TEMPLATE = "templates/invoice/Invoice"; + private final static String INVOICE_TEMPLATE_EXTENSION = ".ods"; + private final static String TEMP_INVOICE_SUFFIX_NAME = "_invoice.ods"; + private final static int ADDRESS_ROW_START = 2; + private final static int ADDRESS_ROW_END = 5; + + private final static int BILLTO_ROW_START = 8; + private final static int BILLTO_ROW_END = 13; + + private final static int PRODUCT_ROW_START = 16; + + private static final Logger LOGGER = LoggerFactory.getLogger( ODSInvoiceModule.class ); + + @Inject + private ZoneService zoneService; + + @Inject + private CountryService countryService; + + @Inject + private ProductPriceUtils priceUtil; + + @Deprecated + @Override + public ByteArrayOutputStream createInvoice(MerchantStore store, Order order, Language language) throws Exception { + // TODO Auto-generated method stub + throw new Exception("Not implemented"); + } + + +/* @Override + public ByteArrayOutputStream createInvoice(MerchantStore store, Order order, Language language) throws Exception { + + + + + List zones = zoneService.getZones(store.getCountry(), language); + Map countries = countryService.getCountriesMap(language); + + //get default template + String template = new StringBuilder().append(INVOICE_TEMPLATE).append("_").append(language.getCode().toLowerCase()).append(INVOICE_TEMPLATE_EXTENSION).toString(); + + //try by language + InputStream is = null; + try { + is = getClass().getClassLoader().getResourceAsStream(template); + } catch (Exception e) { + LOGGER.warn("Cannot open template " + template); + throw new Exception("Cannot open " + template); + } + + if(is==null) { + try { + is = getClass().getClassLoader().getResourceAsStream(new StringBuilder().append(INVOICE_TEMPLATE).append(INVOICE_TEMPLATE_EXTENSION).toString()); + } catch (Exception e) { + LOGGER.warn("Cannot open template " + template); + throw new Exception("Cannot open " + new StringBuilder().append(INVOICE_TEMPLATE).append(INVOICE_TEMPLATE_EXTENSION).toString()); + } + } + + if(is==null) { + LOGGER.warn("Cannot open template " + template); + throw new Exception("Cannot open " + new StringBuilder().append(INVOICE_TEMPLATE).append(INVOICE_TEMPLATE_EXTENSION).toString()); + } + + File file = new File(order.getId() + "_working"); + OutputStream os = new FileOutputStream(file); + IOUtils.copy(is, os); + os.close(); + //File file = new File(resource.toURI().toURL()); + + Sheet sheet = SpreadSheet.createFromFile(file).getSheet(0); + + + //Store name + sheet.setValueAt(store.getStorename(), 0, 0); + + + + //Address + //count store address cell + int storeAddressCell = ADDRESS_ROW_START; + + Map zns = zoneService.getZones(language); + + + //3 + StringBuilder storeAddress = null; + if(!StringUtils.isBlank(store.getStoreaddress())) { + storeAddress = new StringBuilder(); + storeAddress.append(store.getStoreaddress()); + } + if(!StringUtils.isBlank(store.getStorecity())) { + if(storeAddress==null) { + storeAddress = new StringBuilder(); + } else { + storeAddress.append(", "); + } + storeAddress.append(store.getStorecity()); + } + if(storeAddress!=null) { + sheet.setValueAt(storeAddress.toString(), 0, storeAddressCell); + storeAddressCell ++; + } + + //4 + StringBuilder storeProvince = null; + if(store.getZone()!=null) { + storeProvince = new StringBuilder(); + + for(Zone z : zones) { + if(z.getCode().equals(store.getZone().getCode())) { + storeProvince.append(z.getName()); + break; + } + } + + } else { + if(!StringUtils.isBlank(store.getStorestateprovince())) { + storeProvince = new StringBuilder(); + storeProvince.append(store.getStorestateprovince()); + } + } + if(store.getCountry()!=null) { + if(storeProvince==null) { + storeProvince = new StringBuilder(); + } else { + storeProvince.append(", "); + } + + Country c = countries.get(store.getCountry().getIsoCode()); + if(c!=null) { + storeProvince.append(c.getName()); + } else { + storeProvince.append(store.getCountry().getIsoCode()); + } + + } + if(storeProvince!=null) { + sheet.setValueAt(storeProvince.toString(), 0, storeAddressCell); + storeAddressCell ++; + } + + //5 + if(!StringUtils.isBlank(store.getStorepostalcode())) { + sheet.setValueAt(store.getStorepostalcode(), 0, storeAddressCell); + storeAddressCell ++; + } + + //6 + if(!StringUtils.isBlank(store.getStorephone())) { + sheet.setValueAt(store.getStorephone(), 0, storeAddressCell); + } + + //delete address blank lines + for(int i = storeAddressCell; i orderProducts = order.getOrderProducts(); + int productCell = PRODUCT_ROW_START; + for(OrderProduct orderProduct : orderProducts) { + + + String orderProductName = ProductUtils.buildOrderProductDisplayName(orderProduct); + + sheet.setValueAt(orderProductName.toString(), 0, productCell); + + int quantity = orderProduct.getProductQuantity(); + sheet.setValueAt(quantity, 1, productCell); + String amount = priceUtil.getStoreFormatedAmountWithCurrency(store, orderProduct.getOneTimeCharge()); + sheet.setValueAt(amount, 2, productCell); + String t = priceUtil.getStoreFormatedAmountWithCurrency(store, priceUtil.getOrderProductTotalPrice(store, orderProduct)); + sheet.setValueAt(t, 3, productCell); + + productCell++; + + } + + //print totals + productCell++; + Set totals = order.getOrderTotal(); + for(OrderTotal orderTotal : totals) { + + String totalName = orderTotal.getText(); + if(totalName.contains(".")) { + totalName = orderTotal.getTitle(); + } + String totalValue = priceUtil.getStoreFormatedAmountWithCurrency(store,orderTotal.getValue()); + sheet.setValueAt(totalName, 2, productCell); + sheet.setValueAt(totalValue, 3, productCell); + productCell++; + } + + //sheet.getCellAt(0, 0).setImage(arg0) + //sheet.getCellAt(0, 0).setStyleName(arg0) + //sheet.getCellAt(0, 0).getStyle(). + + + //generate invoice file + StringBuilder tempInvoiceName = new StringBuilder(); + tempInvoiceName.append(order.getId()).append(TEMP_INVOICE_SUFFIX_NAME); + File outputFile = new File(tempInvoiceName.toString()); + OOUtils.open(sheet.getSpreadSheet().saveAs(outputFile)); + + + + final OpenDocument doc = new OpenDocument(); + doc.loadFrom(tempInvoiceName.toString()); + + // Open the PDF document + Document document = new Document(PageSize.A4); + + + //File outFile = new File("invoice.pdf"); + + PdfDocument pdf = new PdfDocument(); + + document.addDocListener(pdf); + + //FileOutputStream fileOutputStream = new FileOutputStream(outFile); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + + PdfWriter writer = PdfWriter.getInstance(pdf, outputStream); + pdf.addWriter(writer); + + document.open(); + + // Create a template and a Graphics2D object + Rectangle pageSize = document.getPageSize(); + int w = (int) (pageSize.getWidth() * 0.9); + int h = (int) (pageSize.getHeight() * 0.95); + PdfContentByte cb = writer.getDirectContent(); + PdfTemplate tp = cb.createTemplate(w, h); + + Graphics2D g2 = tp.createPrinterGraphics(w, h, null); + // If you want to prevent copy/paste, you can use + // g2 = tp.createGraphicsShapes(w, h, true, 0.9f); + + tp.setWidth(w); + tp.setHeight(h); + + // Configure the renderer + ODTRenderer renderer = new ODTRenderer(doc); + renderer.setIgnoreMargins(true); + renderer.setPaintMaxResolution(true); + + // Scale the renderer to fit width + renderer.setResizeFactor(renderer.getPrintWidth() / w); + // Render + renderer.paintComponent(g2); + g2.dispose(); + + // Add our spreadsheet in the middle of the page + float offsetX = (float) ((pageSize.getWidth() - w) / 2); + float offsetY = (float) ((pageSize.getHeight() - h) / 2); + cb.addTemplate(tp, offsetX, offsetY); + // Close the PDF document + document.close(); + outputFile.delete();//remove temp file + file.delete();//remove spreadsheet file + is.close(); + return outputStream; + + + + } +*/ +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/ManufacturerShippingCodeOrderTotalModuleImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/ManufacturerShippingCodeOrderTotalModuleImpl.java new file mode 100755 index 0000000000..7aec6deb93 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/ManufacturerShippingCodeOrderTotalModuleImpl.java @@ -0,0 +1,151 @@ +package com.salesmanager.core.business.modules.order.total; + +import java.math.BigDecimal; + +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.OrderSummary; +import com.salesmanager.core.model.order.OrderTotal; +import com.salesmanager.core.model.order.OrderTotalType; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.modules.order.total.OrderTotalPostProcessorModule; + + +/** + * Add variation to the OrderTotal + * This has to be defined in shopizer-core-ordertotal-processors + * @author carlsamson + * + */ +@Component +public class ManufacturerShippingCodeOrderTotalModuleImpl implements OrderTotalPostProcessorModule { + + private static final Logger LOGGER = LoggerFactory.getLogger(ManufacturerShippingCodeOrderTotalModuleImpl.class); + + private String name; + private String code; + + //private StatelessKnowledgeSession orderTotalMethodDecision;//injected from xml file + + //private KnowledgeBase kbase;//injected from xml file + + //@Inject + //KieContainer kieManufacturerBasedPricingContainer; + + + PricingService pricingService; + + + + public PricingService getPricingService() { + return pricingService; + } + + public void setPricingService(PricingService pricingService) { + this.pricingService = pricingService; + } + + @Override + public OrderTotal caculateProductPiceVariation(final OrderSummary summary, ShoppingCartItem shoppingCartItem, Product product, Customer customer, MerchantStore store) + throws Exception { + + + Validate.notNull(product,"product must not be null"); + Validate.notNull(product.getManufacturer(),"product manufacturer must not be null"); + + //requires shipping summary, otherwise return null + if(summary.getShippingSummary()==null) { + return null; + } + + OrderTotalInputParameters inputParameters = new OrderTotalInputParameters(); + inputParameters.setItemManufacturerCode(product.getManufacturer().getCode()); + + + inputParameters.setShippingMethod(summary.getShippingSummary().getShippingOptionCode()); + + LOGGER.debug("Setting input parameters " + inputParameters.toString()); + +/* KieSession kieSession = kieManufacturerBasedPricingContainer.newKieSession(); + kieSession.insert(inputParameters); + kieSession.fireAllRules();*/ + + + //orderTotalMethodDecision.execute(inputParameters); + + + LOGGER.debug("Applied discount " + inputParameters.getDiscount()); + + OrderTotal orderTotal = null; + if(inputParameters.getDiscount() != null) { + orderTotal = new OrderTotal(); + orderTotal.setOrderTotalCode(Constants.OT_DISCOUNT_TITLE); + orderTotal.setOrderTotalType(OrderTotalType.SUBTOTAL); + orderTotal.setTitle(Constants.OT_SUBTOTAL_MODULE_CODE); + + //calculate discount that will be added as a negative value + FinalPrice productPrice = pricingService.calculateProductPrice(product); + + Double discount = inputParameters.getDiscount(); + BigDecimal reduction = productPrice.getFinalPrice().multiply(new BigDecimal(discount)); + reduction = reduction.multiply(new BigDecimal(shoppingCartItem.getQuantity())); + + orderTotal.setValue(reduction); + } + + + + return orderTotal; + + + } + +/* public KnowledgeBase getKbase() { + return kbase; + } + + + public void setKbase(KnowledgeBase kbase) { + this.kbase = kbase; + } + + public StatelessKnowledgeSession getOrderTotalMethodDecision() { + return orderTotalMethodDecision; + } + + public void setOrderTotalMethodDecision(StatelessKnowledgeSession orderTotalMethodDecision) { + this.orderTotalMethodDecision = orderTotalMethodDecision; + }*/ + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + } + + @Override + public String getCode() { + return code; + } + + @Override + public void setCode(String code) { + this.code = code; + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/OrderTotalInputParameters.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/OrderTotalInputParameters.java new file mode 100755 index 0000000000..4bce87765b --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/OrderTotalInputParameters.java @@ -0,0 +1,77 @@ +package com.salesmanager.core.business.modules.order.total; + +import java.util.Date; + +/** + * Input itm to be added to drules engine + * @author carlsamson + * + */ +public class OrderTotalInputParameters { + + private Double discount;//output value set by engine + private String totalCode;//output value set by engine + + //input parameters + private long productId; + private String itemManufacturerCode; + private String itemCategoryCode; + private String shippingMethod; + private String promoCode; + private Date date = new Date(); + + //might add variation based on other objects such as Customer + + public Double getDiscount() { + return discount; + } + public void setDiscount(Double discount) { + this.discount = discount; + } + public String getTotalCode() { + return totalCode; + } + public void setTotalCode(String totalCode) { + this.totalCode = totalCode; + } + public String getItemManufacturerCode() { + return itemManufacturerCode; + } + public void setItemManufacturerCode(String itemManufacturerCode) { + this.itemManufacturerCode = itemManufacturerCode; + } + public String getItemCategoryCode() { + return itemCategoryCode; + } + public void setItemCategoryCode(String itemCategoryCode) { + this.itemCategoryCode = itemCategoryCode; + } + public long getProductId() { + return productId; + } + public void setProductId(long productId) { + this.productId = productId; + } + public String getShippingMethod() { + return shippingMethod; + } + public void setShippingMethod(String shippingMethod) { + this.shippingMethod = shippingMethod; + } + public String getPromoCode() { + return promoCode; + } + public void setPromoCode(String promoCode) { + this.promoCode = promoCode; + } + public Date getDate() { + return date; + } + public void setDate(Date date) { + this.date = date; + } + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/OrderTotalResponse.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/OrderTotalResponse.java new file mode 100644 index 0000000000..4e00e457ba --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/OrderTotalResponse.java @@ -0,0 +1,24 @@ +package com.salesmanager.core.business.modules.order.total; + +public class OrderTotalResponse { + + private Double discount = null; + private String expiration; + + public Double getDiscount() { + return discount; + } + + public void setDiscount(Double discount) { + this.discount = discount; + } + + public String getExpiration() { + return expiration; + } + + public void setExpiration(String expiration) { + this.expiration = expiration; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/PromoCodeCalculatorModule.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/PromoCodeCalculatorModule.java new file mode 100644 index 0000000000..07e1cf44b5 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/order/total/PromoCodeCalculatorModule.java @@ -0,0 +1,118 @@ +package com.salesmanager.core.business.modules.order.total; + +import java.math.BigDecimal; +import java.util.Date; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.kie.api.runtime.KieSession; +import org.kie.internal.io.ResourceFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.configuration.DroolsBeanFactory; +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.OrderSummary; +import com.salesmanager.core.model.order.OrderTotal; +import com.salesmanager.core.model.order.OrderTotalType; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.modules.order.total.OrderTotalPostProcessorModule; + +@Component +public class PromoCodeCalculatorModule implements OrderTotalPostProcessorModule { + + + @Autowired + private DroolsBeanFactory droolsBeanFactory; + + @Autowired + private PricingService pricingService; + + private String name; + private String code; + + @Override + public String getName() { + // TODO Auto-generated method stub + return name; + } + + @Override + public void setName(String name) { + this.name = name; + + } + + @Override + public String getCode() { + // TODO Auto-generated method stub + return code; + } + + @Override + public void setCode(String code) { + this.code = code; + } + + @Override + public OrderTotal caculateProductPiceVariation(OrderSummary summary, ShoppingCartItem shoppingCartItem, + Product product, Customer customer, MerchantStore store) throws Exception { + + Validate.notNull(summary, "OrderTotalSummary must not be null"); + Validate.notNull(store, "MerchantStore must not be null"); + + if(StringUtils.isBlank(summary.getPromoCode())) { + return null; + } + + KieSession kieSession=droolsBeanFactory.getKieSession(ResourceFactory.newClassPathResource("com/salesmanager/drools/rules/PromoCoupon.drl")); + + OrderTotalResponse resp = new OrderTotalResponse(); + + OrderTotalInputParameters inputParameters = new OrderTotalInputParameters(); + inputParameters.setPromoCode(summary.getPromoCode()); + inputParameters.setDate(new Date()); + + kieSession.insert(inputParameters); + kieSession.setGlobal("total",resp); + kieSession.fireAllRules(); + + if(resp.getDiscount() != null) { + + OrderTotal orderTotal = null; + if(resp.getDiscount() != null) { + orderTotal = new OrderTotal(); + orderTotal.setOrderTotalCode(Constants.OT_DISCOUNT_TITLE); + orderTotal.setOrderTotalType(OrderTotalType.SUBTOTAL); + orderTotal.setTitle(Constants.OT_SUBTOTAL_MODULE_CODE); + orderTotal.setText(summary.getPromoCode()); + + //calculate discount that will be added as a negative value + FinalPrice productPrice = pricingService.calculateProductPrice(product); + + Double discount = resp.getDiscount(); + BigDecimal reduction = productPrice.getFinalPrice().multiply(new BigDecimal(discount)); + reduction = reduction.multiply(new BigDecimal(shoppingCartItem.getQuantity())); + + orderTotal.setValue(reduction);//discount value + + //TODO check expiration + } + + + + return orderTotal; + + } + + + + return null; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/utils/EncryptionImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/utils/EncryptionImpl.java new file mode 100755 index 0000000000..ac1d25d215 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/utils/EncryptionImpl.java @@ -0,0 +1,107 @@ +package com.salesmanager.core.business.modules.utils; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import org.apache.commons.lang3.StringUtils; + +import com.salesmanager.core.modules.utils.Encryption; + +public final class EncryptionImpl implements Encryption { + + private final static String IV_P = "fedcba9876543210"; + private final static String KEY_SPEC = "AES"; + private final static String CYPHER_SPEC = "AES/CBC/PKCS5Padding"; + + + + private String secretKey; + + + + @Override + public String encrypt(String value) throws Exception { + + + // value = StringUtils.rightPad(value, 16,"*"); + // Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); + // NEED TO UNDERSTAND WHY PKCS5Padding DOES NOT WORK + Cipher cipher = Cipher.getInstance(CYPHER_SPEC); + SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), KEY_SPEC); + IvParameterSpec ivSpec = new IvParameterSpec(IV_P + .getBytes()); + cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); + byte[] inpbytes = value.getBytes(); + byte[] encrypted = cipher.doFinal(inpbytes); + return bytesToHex(encrypted); + + + } + + @Override + public String decrypt(String value) throws Exception { + + + if (StringUtils.isBlank(value)) + throw new Exception("Nothing to encrypt"); + + // NEED TO UNDERSTAND WHY PKCS5Padding DOES NOT WORK + // Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); + Cipher cipher = Cipher.getInstance(CYPHER_SPEC); + SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), KEY_SPEC); + IvParameterSpec ivSpec = new IvParameterSpec(IV_P + .getBytes()); + cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); + byte[] outText; + outText = cipher.doFinal(hexToBytes(value)); + return new String(outText); + + + } + + + private String bytesToHex(byte[] data) { + if (data == null) { + return null; + } else { + int len = data.length; + String str = ""; + for (byte datum : data) { + if ((datum & 0xFF) < 16) { + str = str + "0" + + Integer.toHexString(datum & 0xFF); + } else { + str = str + Integer.toHexString(datum & 0xFF); + } + + } + return str; + } + } + + private static byte[] hexToBytes(String str) { + if (str == null) { + return null; + } else if (str.length() < 2) { + return null; + } else { + int len = str.length() / 2; + byte[] buffer = new byte[len]; + for (int i = 0; i < len; i++) { + buffer[i] = (byte) Integer.parseInt(str.substring(i * 2, + i * 2 + 2), 16); + } + return buffer; + } + } + + public String getSecretKey() { + return secretKey; + } + + public void setSecretKey(String secretKey) { + this.secretKey = secretKey; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/modules/utils/GeoLocationImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/modules/utils/GeoLocationImpl.java new file mode 100755 index 0000000000..5e8c470f01 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/modules/utils/GeoLocationImpl.java @@ -0,0 +1,62 @@ +package com.salesmanager.core.business.modules.utils; + +import java.net.InetAddress; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.maxmind.geoip2.DatabaseReader; +import com.maxmind.geoip2.model.CityResponse; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.common.Address; +import com.salesmanager.core.modules.utils.GeoLocation; + +/** + * Using Geolite2 City database + * http://dev.maxmind.com/geoip/geoip2/geolite2/#Databases + * @author c.samson + * + */ +public class GeoLocationImpl implements GeoLocation { + + private DatabaseReader reader = null; + private static final Logger LOGGER = LoggerFactory.getLogger( GeoLocationImpl.class ); + + + @Override + public Address getAddress(String ipAddress) throws Exception { + + if(reader==null) { + try { + java.io.InputStream inputFile = GeoLocationImpl.class.getClassLoader().getResourceAsStream("reference/GeoLite2-City.mmdb"); + reader = new DatabaseReader.Builder(inputFile).build(); + } catch(Exception e) { + LOGGER.error("Cannot instantiate IP database",e); + } + } + + Address address = new Address(); + + try { + + CityResponse response = reader.city(InetAddress.getByName(ipAddress)); + + address.setCountry(response.getCountry().getIsoCode()); + address.setPostalCode(response.getPostal().getCode()); + address.setZone(response.getMostSpecificSubdivision().getIsoCode()); + address.setCity(response.getCity().getName()); + + } catch(com.maxmind.geoip2.exception.AddressNotFoundException ne) { + LOGGER.debug("Address not fount in DB " + ne.getMessage()); + } catch(Exception e) { + throw new ServiceException(e); + } + + + return address; + + + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/catalog/CatalogEntryRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/catalog/CatalogEntryRepository.java new file mode 100644 index 0000000000..ddb49d3a57 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/catalog/CatalogEntryRepository.java @@ -0,0 +1,9 @@ +package com.salesmanager.core.business.repositories.catalog.catalog; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.salesmanager.core.model.catalog.catalog.CatalogCategoryEntry; + +public interface CatalogEntryRepository extends JpaRepository { + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/catalog/CatalogRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/catalog/CatalogRepository.java new file mode 100644 index 0000000000..b0ba1af3f2 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/catalog/CatalogRepository.java @@ -0,0 +1,32 @@ +package com.salesmanager.core.business.repositories.catalog.catalog; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.catalog.Catalog; + +import java.util.Optional; + +public interface CatalogRepository extends JpaRepository { + + + @Query("select c from Catalog c " + + "join c.merchantStore cm " + + "left join fetch c.entry ce " + //+ "left join fetch ce.product cep " + + "left join fetch ce.category cec where c.id=?1 and cm.id = ?2") + Optional findById(Long catalogId, Integer merchantId); + + @Query("select c from Catalog c " + + "join c.merchantStore cm " + + "left join fetch c.entry ce " + //+ "left join fetch ce.product cep " + + "left join fetch ce.category cec where c.code=?1 and cm.id = ?2") + Optional findByCode(String code, Integer merchantId); + + @Query("SELECT COUNT(c) > 0 FROM Catalog c " + + "join c.merchantStore cm " + + "WHERE c.code = ?1 and cm.id = ?2") + boolean existsByCode(String code, Integer merchantId); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/catalog/PageableCatalogEntryRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/catalog/PageableCatalogEntryRepository.java new file mode 100644 index 0000000000..9b15599391 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/catalog/PageableCatalogEntryRepository.java @@ -0,0 +1,35 @@ +package com.salesmanager.core.business.repositories.catalog.catalog; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; + +import com.salesmanager.core.model.catalog.catalog.CatalogCategoryEntry; + +public interface PageableCatalogEntryRepository extends PagingAndSortingRepository { + + +/* @Query(value = "select distinct c from CatalogEntry c join fetch c.product cp " + + "join fetch c.category cc " + + "join fetch c.catalog cl " + + "join fetch cl.merchantStore clm " + + "left join fetch cp.descriptions cpd " + + "left join fetch cc.descriptions ccd " + + "where cl.id=?1 and " + + "clm.id=?2 and " + + "cpd.language.id=?3 and (?4 is null or cpd.name like %?4%)", + countQuery = "select count(c) from CatalogEntry c join c.product cp join c.category cc join c.catalog cl join cl.merchantStore clm join cp.descriptions cpd where cl.id=?1 and clm.id=?2 and cpd.language.id=?3 and (?4 is null or cpd.name like %?4%)")*/ + @Query(value = "select distinct c from CatalogCategoryEntry c " + + "join fetch c.category cc " + + "join fetch c.catalog cl " + + "join fetch cl.merchantStore clm " + + "left join fetch cc.descriptions ccd " + + "where cl.id=?1 and " + + "clm.id=?2 and " + + "ccd.language.id=?3", + countQuery = "select count(c) from CatalogCategoryEntry c join c.category cc join c.catalog cl join cl.merchantStore clm join cc.descriptions ccd where cl.id=?1 and clm.id=?2 and ccd.language.id=?3") + Page listByCatalog(Long catalogId, Integer storeId, Integer languageId, String name, Pageable pageable); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/catalog/PageableCatalogRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/catalog/PageableCatalogRepository.java new file mode 100644 index 0000000000..3d88d7a1b8 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/catalog/PageableCatalogRepository.java @@ -0,0 +1,18 @@ +package com.salesmanager.core.business.repositories.catalog.catalog; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; + +import com.salesmanager.core.model.catalog.catalog.Catalog; + +public interface PageableCatalogRepository extends PagingAndSortingRepository { + + + @Query(value = "select distinct c from Catalog c join fetch c.merchantStore cm left join fetch c.entry ce where cm.id=?1 and (?2 is null or c.code like %?2%)", + countQuery = "select count(c) from Catalog c join c.merchantStore cm join c.entry ce where cm.id=?1 and (?2 is null or c.code like %?2%)") + Page listByStore(Integer storeId, String code, Pageable pageable); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/CategoryDescriptionRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/CategoryDescriptionRepository.java new file mode 100644 index 0000000000..5919744923 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/CategoryDescriptionRepository.java @@ -0,0 +1,21 @@ +package com.salesmanager.core.business.repositories.catalog.category; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.category.CategoryDescription; + + +public interface CategoryDescriptionRepository extends JpaRepository { + + + @Query("select c from CategoryDescription c where c.category.id = ?1") + List listByCategoryId(Long categoryId); + + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/CategoryRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/CategoryRepository.java new file mode 100755 index 0000000000..d90180e8e0 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/CategoryRepository.java @@ -0,0 +1,86 @@ +package com.salesmanager.core.business.repositories.catalog.category; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.category.Category; + + +public interface CategoryRepository extends JpaRepository, CategoryRepositoryCustom { + + + @Query("select c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm where cd.seUrl like ?2 and cm.id = ?1 order by c.sortOrder asc") + List listByFriendlyUrl(Integer storeId, String friendlyUrl); + + @Query("select c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm where cd.seUrl=?2 and cm.id = ?1") + Category findByFriendlyUrl(Integer storeId, String friendlyUrl); + + @Query("select c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm where cd.name like %?2% and cdl.id=?3 and cm.id = ?1 order by c.sortOrder asc") + List findByName(Integer storeId, String name, Integer languageId); + + @Query("select c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm where c.code=?2 and cm.id = ?1") + Category findByCode(Integer storeId, String code); + + @Query("select c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm where c.code in (?2) and cdl.id=?3 and cm.id = ?1 order by c.sortOrder asc") + List findByCodes(Integer storeId, List codes, Integer languageId); + + @Query("select c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm where c.id in (?2) and cdl.id=?3 and cm.id = ?1 order by c.sortOrder asc") + List findByIds(Integer storeId, List ids, Integer languageId); + + @Query("select c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm left join fetch c.categories where cm.id=?1 and c.id = ?2 and cdl.id=?3") + Category findById(Integer storeId, Long categoryId, Integer languageId); + + @Query("select c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm left join fetch c.categories where c.id = ?1 and cdl.id=?2") + Category findByIdAndLanguage(Long categoryId, Integer languageId); + + @Query("select c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm left join fetch c.categories where c.id = ?1 and cm.id=?2") + Category findByIdAndStore(Long categoryId, Integer storeId); + + @Query("select c from Category c left join fetch c.parent cp left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm left join fetch c.categories where cm.code=?2 and c.id = ?1") + Category findById(Long categoryId, String merchant); + + @Query("select c from Category c left join fetch c.parent cp left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm left join fetch c.categories where c.id = ?1") + Optional findById(Long categoryId); + + @Query("select c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm where cm.code=?1 and c.code=?2") + Category findByCode(String merchantStoreCode, String code); + + @Query("select c from Category c join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm where c.id=?1") + Category findOne(Long categoryId); + + @Query("select distinct c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm where cm.id=?1 and c.lineage like %?2% order by c.lineage, c.sortOrder asc") + List findByLineage(Integer merchantId, String linenage); + + @Query("select distinct c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm where cm.code= ?1 and c.lineage like %?2% order by c.lineage, c.sortOrder asc") + List findByLineage(String storeCode, String linenage); + + @Query("select distinct c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm where cm.id=?1 and c.depth >= ?2 order by c.lineage, c.sortOrder asc") + List findByDepth(Integer merchantId, int depth); + + @Query("select distinct c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm where cm.id=?1 and cdl.id=?3 and c.depth >= ?2 order by c.lineage, c.sortOrder asc") + List findByDepth(Integer merchantId, int depth, Integer languageId); + + @Query("select distinct c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm where cm.id=?1 and cdl.id=?3 and c.depth >= ?2 and (?4 is null or cd.name like %?4%) order by c.lineage, c.sortOrder asc") + List find(Integer merchantId, int depth, Integer languageId, String name); + + @Query("select distinct c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm where cm.id=?1 and cdl.id=?3 and c.depth >= ?2 and c.featured=true order by c.lineage, c.sortOrder asc") + List findByDepthFilterByFeatured(Integer merchantId, int depth, Integer languageId); + + @Query("select distinct c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm left join fetch c.parent cp where cp.id=?1 and cdl.id=?2 order by c.lineage, c.sortOrder asc") + List findByParent(Long parentId, Integer languageId); + + @Query("select distinct c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm where cm.id=?1 and cdl.id=?2 order by c.lineage, c.sortOrder asc") + List findByStore(Integer merchantId, Integer languageId); + + @Query("select distinct c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm where cm.id=?1 order by c.lineage, c.sortOrder asc") + List findByStore(Integer merchantId); + + @Query("select count(distinct c) from Category as c where c.merchantStore.id=?1") + int count(Integer storeId); + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/CategoryRepositoryCustom.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/CategoryRepositoryCustom.java new file mode 100755 index 0000000000..d46ef44014 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/CategoryRepositoryCustom.java @@ -0,0 +1,17 @@ +package com.salesmanager.core.business.repositories.catalog.category; + +import java.util.List; + +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.merchant.MerchantStore; + +public interface CategoryRepositoryCustom { + + List countProductsByCategories(MerchantStore store, + List categoryIds); + + List listByStoreAndParent(MerchantStore store, Category category); + + List listByProduct(MerchantStore store, Long product); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/CategoryRepositoryImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/CategoryRepositoryImpl.java new file mode 100755 index 0000000000..ba6ba6f8df --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/CategoryRepositoryImpl.java @@ -0,0 +1,121 @@ +package com.salesmanager.core.business.repositories.catalog.category; + +import java.util.Date; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; + +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.merchant.MerchantStore; + + +public class CategoryRepositoryImpl implements CategoryRepositoryCustom { + + @PersistenceContext + private EntityManager em; + + @Override + public List countProductsByCategories(MerchantStore store, List categoryIds) { + + + StringBuilder qs = new StringBuilder(); + qs.append("select category.id, count(product.id) from Product product "); + qs.append("inner join product.categories category "); + qs.append("where category.id in (:cid) "); + qs.append("and product.available=true and product.dateAvailable<=:dt "); + qs.append("group by category.id"); + + String hql = qs.toString(); + Query q = this.em.createQuery(hql); + + q.setParameter("cid", categoryIds); + q.setParameter("dt", new Date()); + + + + @SuppressWarnings("unchecked") + List counts = q.getResultList(); + + + return counts; + + + } + + @SuppressWarnings("unchecked") + @Override + public List listByStoreAndParent(MerchantStore store, Category category) { + + StringBuilder queryBuilder = new StringBuilder(); + queryBuilder.append("select c from Category c join fetch c.merchantStore cm "); + + if (store == null) { + if (category == null) { + //query.from(qCategory) + queryBuilder.append(" where c.parent IsNull "); + //.where(qCategory.parent.isNull()) + //.orderBy(qCategory.sortOrder.asc(),qCategory.id.desc()); + } else { + //query.from(qCategory) + queryBuilder.append(" join fetch c.parent cp where cp.id =:cid "); + //.where(qCategory.parent.eq(category)) + //.orderBy(qCategory.sortOrder.asc(),qCategory.id.desc()); + } + } else { + if (category == null) { + //query.from(qCategory) + queryBuilder.append(" where c.parent IsNull and cm.id=:mid "); + //.where(qCategory.parent.isNull() + // .and(qCategory.merchantStore.eq(store))) + //.orderBy(qCategory.sortOrder.asc(),qCategory.id.desc()); + } else { + //query.from(qCategory) + queryBuilder.append(" join fetch c.parent cp where cp.id =:cId and cm.id=:mid "); + //.where(qCategory.parent.eq(category) + // .and(qCategory.merchantStore.eq(store))) + //.orderBy(qCategory.sortOrder.asc(),qCategory.id.desc()); + } + } + + queryBuilder.append(" order by c.sortOrder asc"); + + String hql = queryBuilder.toString(); + Query q = this.em.createQuery(hql); + + q.setParameter("cid", category.getId()); + if (store != null) { + q.setParameter("mid", store.getId()); + } + + + return q.getResultList(); + } + + @Override + public List listByProduct(MerchantStore store, Long product) { + + + + StringBuilder qs = new StringBuilder(); + qs.append("select category from Product product "); + qs.append("inner join product.categories category inner join product.merchantStore pm "); + qs.append("where product.id=:id and pm.id=:mid "); + qs.append("group by category.id"); + + String hql = qs.toString(); + Query q = this.em.createQuery(hql); + + q.setParameter("id", product); + q.setParameter("mid", store.getId()); + + @SuppressWarnings("unchecked") + List c = q.getResultList(); + + + return c; + + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/PageableCategoryRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/PageableCategoryRepository.java new file mode 100644 index 0000000000..13b9b72735 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/PageableCategoryRepository.java @@ -0,0 +1,18 @@ +package com.salesmanager.core.business.repositories.catalog.category; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; +import com.salesmanager.core.model.catalog.category.Category; + +public interface PageableCategoryRepository extends PagingAndSortingRepository { + + + @Query(value = "select distinct c from Category c left join fetch c.descriptions cd join fetch cd.language cdl join fetch c.merchantStore cm where cm.id=?1 and cdl.id=?2 and (cd.name like %?3% or ?3 is null) order by c.lineage, c.sortOrder asc", + countQuery = "select count(c) from Category c join c.descriptions cd join c.merchantStore cm where cm.id=?1 and cd.language.id=?2 and (cd.name like %?3% or ?3 is null)") + Page listByStore(Integer storeId, Integer languageId, String name, Pageable pageable); + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/PageableCategoryRepositoryCustom.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/PageableCategoryRepositoryCustom.java new file mode 100644 index 0000000000..89cf2d9a1b --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/PageableCategoryRepositoryCustom.java @@ -0,0 +1,13 @@ +package com.salesmanager.core.business.repositories.catalog.category; + + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import com.salesmanager.core.model.catalog.category.Category; + +public interface PageableCategoryRepositoryCustom { + + Page listByStore(Integer storeId, Integer languageId, String name, Pageable pageable); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/PageableCategoryRepositoryImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/PageableCategoryRepositoryImpl.java new file mode 100644 index 0000000000..4df6fc5ad5 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/category/PageableCategoryRepositoryImpl.java @@ -0,0 +1,33 @@ +package com.salesmanager.core.business.repositories.catalog.category; + +import com.salesmanager.core.model.catalog.category.Category; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; + + +public class PageableCategoryRepositoryImpl implements PageableCategoryRepositoryCustom { + + @PersistenceContext + private EntityManager em; + @SuppressWarnings("unchecked") + @Override + public Page listByStore(Integer storeId, Integer languageId, String name, Pageable pageable) { + Query query = em.createNamedQuery("CATEGORY.listByStore"); + Query countQueryResult = em.createNamedQuery("CATEGORY.listByStore.count"); + query.setParameter(1, storeId); + query.setParameter(2, languageId); + query.setParameter(3, name == null ? "" : name); + query.setMaxResults(pageable.getPageSize()); + query.setFirstResult(pageable.getPageNumber() * pageable.getPageSize()); + return new PageImpl( + query.getResultList(), + pageable, + countQueryResult.getMaxResults()); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/ProductRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/ProductRepository.java new file mode 100755 index 0000000000..5d3df2f9b6 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/ProductRepository.java @@ -0,0 +1,27 @@ +package com.salesmanager.core.business.repositories.catalog.product; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.product.Product; + + +public interface ProductRepository extends JpaRepository, ProductRepositoryCustom { + + + @Query(value="select case when count(p)> 0 then true else false end" + + " from Product p join p.merchantStore pm" + + " left join p.Variants pinst " + + " where pinst.sku=?1 or p.sku=?1 and pm.id=?2",nativeQuery = true) + boolean existsBySku(String sku, Integer store); + + @Query( + + value = "select p.PRODUCT_ID from {h-schema}PRODUCT p join {h-schema}MERCHANT_STORE m ON p.MERCHANT_ID = m.MERCHANT_ID left join {h-schema}PRODUCT_VARIANT i ON i.PRODUCT_ID = p.PRODUCT_ID where p.SKU=?1 or i.SKU=?1 and m.MERCHANT_ID=?2", + nativeQuery = true + ) + List findBySku(String sku, Integer consultId); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/ProductRepositoryCustom.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/ProductRepositoryCustom.java new file mode 100755 index 0000000000..00c5418637 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/ProductRepositoryCustom.java @@ -0,0 +1,65 @@ +package com.salesmanager.core.business.repositories.catalog.product; + +import java.util.List; +import java.util.Locale; +import java.util.Set; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.ProductCriteria; +import com.salesmanager.core.model.catalog.product.ProductList; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.tax.taxclass.TaxClass; + +public interface ProductRepositoryCustom { + + + ProductList listByStore(MerchantStore store, Language language, + ProductCriteria criteria); + + Product getProductWithOnlyMerchantStoreById(Long productId); + + Product getByFriendlyUrl(MerchantStore store,String seUrl, Locale locale); + + List getProductsListByCategories(@SuppressWarnings("rawtypes") Set categoryIds); + + List getProductsListByCategories(Set categoryIds, + Language language); + + List getProductsListByIds(Set productIds); + + List listByTaxClass(TaxClass taxClass); + + List listByStore(MerchantStore store); + + Product getProductForLocale(long productId, Language language, + Locale locale); + + Product getById(Long productId); + Product getById(Long productId, MerchantStore merchant); + + /** + * Get product by code + * @deprecated + * This method is no longer acceptable to get product by code. + *

    Use {@link ProductService#getBySku(sku, store)} instead. + */ + @Deprecated + Product getByCode(String productCode, Language language); + + /** + * Get product by code + * @deprecated + * This method is no longer acceptable to get product by code. + *

    Use {@link ProductService#getBySku(sku, store)} instead. + */ + @Deprecated + Product getByCode(String productCode, MerchantStore store); + + Product getById(Long productId, MerchantStore store, Language language); + + List getProductsForLocale(MerchantStore store, + Set categoryIds, Language language, Locale locale); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/ProductRepositoryImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/ProductRepositoryImpl.java new file mode 100755 index 0000000000..754c86d539 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/ProductRepositoryImpl.java @@ -0,0 +1,1245 @@ +package com.salesmanager.core.business.repositories.catalog.product; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +import javax.persistence.EntityManager; +import javax.persistence.NoResultException; +import javax.persistence.NonUniqueResultException; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.utils.RepositoryHelper; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.ProductCriteria; +import com.salesmanager.core.model.catalog.product.ProductList; +import com.salesmanager.core.model.catalog.product.attribute.AttributeCriteria; +import com.salesmanager.core.model.common.GenericEntityList; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.tax.taxclass.TaxClass; + +public class ProductRepositoryImpl implements ProductRepositoryCustom { + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductRepositoryImpl.class); + + @PersistenceContext + private EntityManager em; + + @Override + public Product getById(Long productId, MerchantStore store) { + return get(productId, store); + } + + @Override + public Product getById(Long productId) { + return get(productId, null); + } + + + @Override + public Product getProductWithOnlyMerchantStoreById(Long productId) { + final String hql = "select distinct p from Product as p " + + "join fetch p.merchantStore merch " + + "where p.id=:pid"; + + final Query q = this.em.createQuery(hql); + q.setParameter("pid", productId); + + try { + return (Product)q.getSingleResult(); + } catch (NoResultException ignored) { + return null; + } + } + + + + private Product get(Long productId, MerchantStore merchant) { + + try { + + Integer merchantId = null; + Integer parentId = null; + List ids = new ArrayList(); + + StringBuilder qs = new StringBuilder(); + qs.append(productQueryV2()); + + qs.append("where p.id=:pid"); + if (merchant != null) { + merchantId = merchant.getId(); + ids.add(merchantId); + if(merchant.getParent()!=null) { + parentId = merchant.getParent().getId(); + ids.add(parentId); + } + } + + if(merchantId != null) { + //qs.append(" and merch.id=:mid"); + qs.append(" and merch.id in (:mid)"); + } + + String hql = qs.toString(); + Query q = this.em.createQuery(hql); + + q.setParameter("pid", productId); + + + if(merchantId != null) { + //q.setParameter("mid", merchant.getId()); + q.setParameter("mid", ids); + } + + return (Product) q.getSingleResult(); + + } catch (javax.persistence.NoResultException ers) { + return null; + } + + } + + @Override + public Product getByCode(String productCode, Language language) { + + try { + + StringBuilder qs = new StringBuilder(); + qs.append("select distinct p from Product as p "); + qs.append("join fetch p.availabilities pa "); + qs.append("join fetch p.descriptions pd "); + qs.append("join fetch p.merchantStore pm "); + qs.append("left join fetch pa.prices pap "); + qs.append("left join fetch pap.descriptions papd "); + + qs.append("left join fetch p.categories categs "); + qs.append("left join fetch categs.descriptions categsd "); + + // images + qs.append("left join fetch p.images images "); + // options + qs.append("left join fetch p.attributes pattr "); + qs.append("left join fetch pattr.productOption po "); + qs.append("left join fetch po.descriptions pod "); + qs.append("left join fetch pattr.productOptionValue pov "); + qs.append("left join fetch pov.descriptions povd "); + qs.append("left join fetch p.relationships pr "); + // other lefts + qs.append("left join fetch p.manufacturer manuf "); + qs.append("left join fetch manuf.descriptions manufd "); + qs.append("left join fetch p.type type "); + qs.append("left join fetch p.taxClass tx "); + + // RENTAL + //qs.append("left join fetch p.owner owner "); + + qs.append("where p.sku=:code "); + qs.append("and pd.language.id=:lang and papd.language.id=:lang"); + // this cannot be done on child elements from left join + // qs.append("and pod.languageId=:lang and povd.languageId=:lang"); + + String hql = qs.toString(); + Query q = this.em.createQuery(hql); + + q.setParameter("code", productCode); + q.setParameter("lang", language.getId()); + + return (Product) q.getSingleResult(); + + } catch (javax.persistence.NoResultException ers) { + return null; + } + + } + + @Override + public Product getByCode(String productCode, MerchantStore store) { + + try { + + StringBuilder qs = new StringBuilder(); + qs.append("select distinct p from Product as p "); + qs.append("join fetch p.descriptions pd "); + qs.append("join fetch p.merchantStore pm "); + + qs.append("left join fetch p.categories categs "); + qs.append("left join fetch categs.descriptions categsd "); + + // options + qs.append("left join fetch p.attributes pattr "); + qs.append("left join fetch pattr.productOption po "); + qs.append("left join fetch po.descriptions pod "); + qs.append("left join fetch pattr.productOptionValue pov "); + qs.append("left join fetch pov.descriptions povd "); + qs.append("left join fetch p.relationships pr "); + // other lefts + qs.append("left join fetch p.manufacturer manuf "); + qs.append("left join fetch manuf.descriptions manufd "); + qs.append("left join fetch p.type type "); + + + qs.append("where p.sku=:code and pm.id=:id"); + + String hql = qs.toString(); + Query q = this.em.createQuery(hql); + + q.setParameter("code", productCode); + q.setParameter("id", store.getId()); + + return (Product) q.getSingleResult(); + + } catch (javax.persistence.NoResultException ers) { + return null; + } + + } + + public Product getByFriendlyUrl(MerchantStore store, String seUrl, Locale locale) { + + List regionList = new ArrayList<>(); + regionList.add("*"); + regionList.add(locale.getCountry()); + + StringBuilder qs = new StringBuilder(); + qs.append("select distinct p from Product as p "); + qs.append("join fetch p.availabilities pa "); + qs.append("join fetch p.descriptions pd "); + qs.append("join fetch p.merchantStore pm "); + qs.append("left join fetch pa.prices pap "); + qs.append("left join fetch pap.descriptions papd "); + + qs.append("left join fetch p.categories categs "); + qs.append("left join fetch categs.descriptions categsd "); + + // images + qs.append("left join fetch p.images images "); + // options + qs.append("left join fetch p.attributes pattr "); + qs.append("left join fetch pattr.productOption po "); + qs.append("left join fetch po.descriptions pod "); + qs.append("left join fetch pattr.productOptionValue pov "); + qs.append("left join fetch pov.descriptions povd "); + qs.append("left join fetch p.relationships pr "); + // other lefts + qs.append("left join fetch p.manufacturer manuf "); + qs.append("left join fetch manuf.descriptions manufd "); + qs.append("left join fetch p.type type "); + qs.append("left join fetch p.taxClass tx "); + + // RENTAL + //qs.append("left join fetch p.owner owner "); + + qs.append("where pa.region in (:lid) "); + qs.append("and pd.seUrl=:seUrl "); + qs.append("and p.available=true and p.dateAvailable<=:dt "); + qs.append("order by pattr.productOptionSortOrder "); + + String hql = qs.toString(); + Query q = this.em.createQuery(hql); + + q.setParameter("lid", regionList); + q.setParameter("dt", new Date()); + q.setParameter("seUrl", seUrl); + + Product p = null; + + try { + List products = q.getResultList(); + if (products.size() > 1) { + LOGGER.error("Found multiple products for list of criterias with main criteria [" + seUrl + "]"); + } + // p = (Product)q.getSingleResult(); + p = products.get(0); + } catch (javax.persistence.NoResultException ignore) { + + } + + return p; + + } + + @Override + public List getProductsForLocale(MerchantStore store, Set categoryIds, Language language, + Locale locale) { + + ProductList products = this.getProductsListForLocale(store, categoryIds, language, locale, 0, -1); + + return products.getProducts(); + } + + @Override + public Product getProductForLocale(long productId, Language language, Locale locale) { + + List regionList = new ArrayList(); + regionList.add("*"); + regionList.add(locale.getCountry()); + + StringBuilder qs = new StringBuilder(); + qs.append("select distinct p from Product as p "); + qs.append("join fetch p.availabilities pa "); + qs.append("join fetch p.descriptions pd "); + qs.append("join fetch p.merchantStore pm "); + qs.append("left join fetch pa.prices pap "); + qs.append("left join fetch pap.descriptions papd "); + + // images + qs.append("left join fetch p.images images "); + // options + qs.append("left join fetch p.attributes pattr "); + qs.append("left join fetch pattr.productOption po "); + qs.append("left join fetch po.descriptions pod "); + qs.append("left join fetch pattr.productOptionValue pov "); + qs.append("left join fetch pov.descriptions povd "); + qs.append("left join fetch p.relationships pr "); + // other lefts + qs.append("left join fetch p.manufacturer manuf "); + qs.append("left join fetch manuf.descriptions manufd "); + qs.append("left join fetch p.type type "); + qs.append("left join fetch p.taxClass tx "); + + // RENTAL + //qs.append("left join fetch p.owner owner "); + + qs.append("where p.id=:pid and pa.region in (:lid) "); + qs.append("and pd.language.id=:lang and papd.language.id=:lang "); + qs.append("and p.available=true and p.dateAvailable<=:dt "); + // this cannot be done on child elements from left join + // qs.append("and pod.languageId=:lang and povd.languageId=:lang"); + + String hql = qs.toString(); + Query q = this.em.createQuery(hql); + + q.setParameter("pid", productId); + q.setParameter("lid", regionList); + q.setParameter("dt", new Date()); + q.setParameter("lang", language.getId()); + + @SuppressWarnings("unchecked") + List results = q.getResultList(); + if (results.isEmpty()) + return null; + else if (results.size() == 1) + return results.get(0); + throw new NonUniqueResultException(); + + } + + @SuppressWarnings("rawtypes") + @Override + public List getProductsListByCategories(Set categoryIds) { + + // List regionList = new ArrayList(); + // regionList.add("*"); + // regionList.add(locale.getCountry()); + + // TODO Test performance + /** + * Testing in debug mode takes a long time with this query running in + * normal mode is fine + */ + + StringBuilder qs = new StringBuilder(); + qs.append("select distinct p from Product as p "); + qs.append("join fetch p.merchantStore merch "); + qs.append("join fetch p.availabilities pa "); + qs.append("left join fetch pa.prices pap "); + + qs.append("join fetch p.descriptions pd "); + qs.append("join fetch p.categories categs "); + + qs.append("left join fetch pap.descriptions papd "); + + // images + qs.append("left join fetch p.images images "); + + // options (do not need attributes for listings) + qs.append("left join fetch p.attributes pattr "); + qs.append("left join fetch pattr.productOption po "); + qs.append("left join fetch po.descriptions pod "); + qs.append("left join fetch pattr.productOptionValue pov "); + qs.append("left join fetch pov.descriptions povd "); + + // other lefts + qs.append("left join fetch p.manufacturer manuf "); + qs.append("left join fetch p.type type "); + qs.append("left join fetch p.taxClass tx "); + + // RENTAL + //qs.append("left join fetch p.owner owner "); + + // qs.append("where pa.region in (:lid) "); + qs.append("where categs.id in (:cid)"); + + String hql = qs.toString(); + Query q = this.em.createQuery(hql); + + q.setParameter("cid", categoryIds); + + @SuppressWarnings("unchecked") + List products = q.getResultList(); + + return products; + + } + + @Override + public List getProductsListByCategories(Set categoryIds, Language language) { + + // List regionList = new ArrayList(); + // regionList.add("*"); + // regionList.add(locale.getCountry()); + + // TODO Test performance + /** + * Testing in debug mode takes a long time with this query running in + * normal mode is fine + */ + + StringBuilder qs = new StringBuilder(); + qs.append("select distinct p from Product as p "); + qs.append("join fetch p.merchantStore merch "); + qs.append("join fetch p.availabilities pa "); + qs.append("left join fetch pa.prices pap "); + + qs.append("join fetch p.descriptions pd "); + qs.append("join fetch p.categories categs "); + qs.append("left join fetch pap.descriptions papd "); + + // images + qs.append("left join fetch p.images images "); + + // options (do not need attributes for listings) + qs.append("left join fetch p.attributes pattr "); + qs.append("left join fetch pattr.productOption po "); + qs.append("left join fetch po.descriptions pod "); + qs.append("left join fetch pattr.productOptionValue pov "); + qs.append("left join fetch pov.descriptions povd "); + + // other lefts + qs.append("left join fetch p.manufacturer manuf "); + qs.append("left join fetch manuf.descriptions manufd "); + qs.append("left join fetch p.type type "); + qs.append("left join fetch p.taxClass tx "); + + // RENTAL + //qs.append("left join fetch p.owner owner "); + + // qs.append("where pa.region in (:lid) "); + qs.append("where categs.id in (:cid) "); + // qs.append("and pd.language.id=:lang and papd.language.id=:lang and + // manufd.language.id=:lang "); + qs.append("and pd.language.id=:lang and papd.language.id=:lang "); + qs.append("and p.available=true and p.dateAvailable<=:dt "); + + String hql = qs.toString(); + Query q = this.em.createQuery(hql); + + q.setParameter("cid", categoryIds); + q.setParameter("lang", language.getId()); + q.setParameter("dt", new Date()); + + @SuppressWarnings("unchecked") + List products = q.getResultList(); + + return products; + + } + + @Override + public List getProductsListByIds(Set productds) { + StringBuilder qs = new StringBuilder(); + qs.append(productQueryV2()); + qs.append("where p.id in (:pid) "); + qs.append("and p.available=true and p.dateAvailable<=:dt "); + + String hql = qs.toString(); + Query q = this.em.createQuery(hql); + + q.setParameter("pid", productds); + q.setParameter("dt", new Date()); + + return q.getResultList(); + } + + /** + * This query is used for category listings. All collections are not fully + * loaded, only the required objects so the listing page can display + * everything related to all products + */ + @SuppressWarnings({ "rawtypes", "unchecked", "unused" }) + private ProductList getProductsListForLocale(MerchantStore store, Set categoryIds, Language language, Locale locale, + int first, int max) { + + List regionList = new ArrayList(); + regionList.add(Constants.ALL_REGIONS); + if (locale != null) { + regionList.add(locale.getCountry()); + } + + ProductList productList = new ProductList(); + + Query countQ = this.em.createQuery( + "select count(p) from Product as p INNER JOIN p.availabilities pa INNER JOIN p.categories categs where p.merchantStore.id=:mId and categs.id in (:cid) and pa.region in (:lid) and p.available=1 and p.dateAvailable<=:dt"); + + countQ.setParameter("cid", categoryIds); + countQ.setParameter("lid", regionList); + countQ.setParameter("dt", new Date()); + countQ.setParameter("mId", store.getId()); + + Number count = (Number) countQ.getSingleResult(); + + productList.setTotalCount(count.intValue()); + + if (count.intValue() == 0) + return productList; + + StringBuilder qs = new StringBuilder(); + qs.append("select p from Product as p "); + qs.append("join fetch p.merchantStore merch "); + qs.append("join fetch p.availabilities pa "); + qs.append("left join fetch pa.prices pap "); + + qs.append("join fetch p.descriptions pd "); + qs.append("join fetch p.categories categs "); + + // not necessary + // qs.append("join fetch pap.descriptions papd "); + + // images + qs.append("left join fetch p.images images "); + + // options (do not need attributes for listings) + // qs.append("left join fetch p.attributes pattr "); + // qs.append("left join fetch pattr.productOption po "); + // qs.append("left join fetch po.descriptions pod "); + // qs.append("left join fetch pattr.productOptionValue pov "); + // qs.append("left join fetch pov.descriptions povd "); + + // other lefts + qs.append("left join fetch p.manufacturer manuf "); + qs.append("left join fetch manuf.descriptions manufd "); + qs.append("left join fetch p.type type "); + qs.append("left join fetch p.taxClass tx "); + + // RENTAL + //qs.append("left join fetch p.owner owner "); + + // qs.append("where pa.region in (:lid) "); + qs.append("where p.merchantStore.id=mId and categs.id in (:cid) and pa.region in (:lid) "); + // qs.append("and p.available=true and p.dateAvailable<=:dt and + // pd.language.id=:lang and manufd.language.id=:lang"); + qs.append("and p.available=true and p.dateAvailable<=:dt and pd.language.id=:lang"); + qs.append(" order by p.sortOrder asc"); + + String hql = qs.toString(); + Query q = this.em.createQuery(hql); + + q.setParameter("cid", categoryIds); + q.setParameter("lid", regionList); + q.setParameter("dt", new Date()); + q.setParameter("lang", language.getId()); + q.setParameter("mId", store.getId()); + + q.setFirstResult(first); + if (max > 0) { + int maxCount = first + max; + + q.setMaxResults(Math.min(maxCount, count.intValue())); + } + + List products = q.getResultList(); + productList.setProducts(products); + + return productList; + + } + + /** + * This query is used for filtering products based on criterias + * Main query for getting product list based on input criteria + * ze method + * + * @param store + * @param first + * @param max + * @return + */ + @Override + public ProductList listByStore(MerchantStore store, Language language, ProductCriteria criteria) { + + ProductList productList = new ProductList(); + + StringBuilder countBuilderSelect = new StringBuilder(); + countBuilderSelect.append("select count(distinct p) from Product as p"); + + StringBuilder countBuilderWhere = new StringBuilder(); + countBuilderWhere.append(" where p.merchantStore.id=:mId"); + + if (!CollectionUtils.isEmpty(criteria.getProductIds())) { + countBuilderWhere.append(" and p.id in (:pId)"); + } + + countBuilderSelect.append(" inner join p.descriptions pd"); + if (criteria.getLanguage() != null && !criteria.getLanguage().equals("_all")) { + countBuilderWhere.append(" and pd.language.code=:lang"); + } + + if (!StringUtils.isBlank(criteria.getProductName())) { + countBuilderWhere.append(" and lower(pd.name) like:nm"); + } + + if (!CollectionUtils.isEmpty(criteria.getCategoryIds())) { + countBuilderSelect.append(" INNER JOIN p.categories categs"); + countBuilderWhere.append(" and categs.id in (:cid)"); + } + + if (criteria.getManufacturerId() != null) { + countBuilderSelect.append(" INNER JOIN p.manufacturer manuf"); + countBuilderWhere.append(" and manuf.id = :manufid"); + } + + // todo type + + // sku + if (!StringUtils.isBlank(criteria.getCode())) { + countBuilderWhere.append(" and lower(p.sku) like :sku"); + } + + // RENTAL + /** + if (!StringUtils.isBlank(criteria.getStatus())) { + countBuilderWhere.append(" and p.rentalStatus = :status"); + } + **/ + + /** + if (criteria.getOwnerId() != null) { + countBuilderSelect.append(" INNER JOIN p.owner owner"); + countBuilderWhere.append(" and owner.id = :ownerid");666 + } + **/ + + + + /** + * attributes / options values + * origin allows skipping attributes join in admin + */ + //attribute or option values + if (criteria.getOrigin().equals(ProductCriteria.ORIGIN_SHOP) + && CollectionUtils.isNotEmpty(criteria.getAttributeCriteria()) + || CollectionUtils.isNotEmpty(criteria.getOptionValueIds())) { + + countBuilderSelect.append(" INNER JOIN p.attributes pattr"); + countBuilderSelect.append(" INNER JOIN pattr.productOption po"); + countBuilderSelect.append(" INNER JOIN pattr.productOptionValue pov "); + countBuilderSelect.append(" INNER JOIN pov.descriptions povd "); + + if(CollectionUtils.isNotEmpty(criteria.getAttributeCriteria())) { + int count = 0; + for (AttributeCriteria attributeCriteria : criteria.getAttributeCriteria()) { + if (count == 0) { + countBuilderWhere.append(" and po.code =:").append(attributeCriteria.getAttributeCode()); + countBuilderWhere.append(" and povd.description like :").append("val").append(count) + .append(attributeCriteria.getAttributeCode()); + } + count++; + } + if (criteria.getLanguage() != null && !criteria.getLanguage().equals("_all")) { + countBuilderWhere.append(" and povd.language.code=:lang"); + } + } + + if(CollectionUtils.isNotEmpty(criteria.getOptionValueIds())) { + countBuilderWhere.append(" and pov.id in (:povid)"); + } + } + + if (criteria.getAvailable() != null) { + if (criteria.getAvailable()) { + countBuilderWhere.append(" and p.available=true and p.dateAvailable<=:dt"); + } else { + countBuilderWhere.append(" and p.available=false or p.dateAvailable>:dt"); + } + } + + + + Query countQ = this.em.createQuery(countBuilderSelect.toString() + countBuilderWhere.toString()); + + countQ.setParameter("mId", store.getId()); + + /**/ + if (criteria.getOrigin().equals(ProductCriteria.ORIGIN_SHOP) + && !CollectionUtils.isEmpty(criteria.getCategoryIds())) { + countQ.setParameter("cid", criteria.getCategoryIds()); + } + + /**/ + if(criteria.getOrigin().equals(ProductCriteria.ORIGIN_SHOP) + && CollectionUtils.isNotEmpty(criteria.getOptionValueIds())) { + countQ.setParameter("povid", criteria.getOptionValueIds()); + } + + if (criteria.getAvailable() != null) { + countQ.setParameter("dt", new Date()); + } + + if (!StringUtils.isBlank(criteria.getCode())) { + countQ.setParameter("sku", + new StringBuilder().append("%").append(criteria.getCode().toLowerCase()).append("%").toString()); + } + + if (criteria.getManufacturerId() != null) { + countQ.setParameter("manufid", criteria.getManufacturerId()); + } + + + /**/ + if (criteria.getOrigin().equals(ProductCriteria.ORIGIN_SHOP) + && !CollectionUtils.isEmpty(criteria.getAttributeCriteria())) { + int count = 0; + for (AttributeCriteria attributeCriteria : criteria.getAttributeCriteria()) { + countQ.setParameter(attributeCriteria.getAttributeCode(), attributeCriteria.getAttributeCode()); + countQ.setParameter("val" + count + attributeCriteria.getAttributeCode(), + "%" + attributeCriteria.getAttributeValue() + "%"); + count++; + } + } + + if (criteria.getLanguage() != null && !criteria.getLanguage().equals("_all")) { + countQ.setParameter("lang", language.getCode()); + } + + if (!StringUtils.isBlank(criteria.getProductName())) { + countQ.setParameter("nm", new StringBuilder().append("%").append(criteria.getProductName().toLowerCase()) + .append("%").toString()); + } + + if (!CollectionUtils.isEmpty(criteria.getProductIds())) { + countQ.setParameter("pId", criteria.getProductIds()); + } + + // RENTAL + /** + if (!StringUtils.isBlank(criteria.getStatus())) { + countQ.setParameter("status", criteria.getStatus()); + } + **/ + + if (criteria.getOwnerId() != null) { + countQ.setParameter("ownerid", criteria.getOwnerId()); + } + + Number count = (Number) countQ.getSingleResult(); + productList.setTotalCount(count.intValue()); + + if (count.intValue() == 0) + return productList; + + StringBuilder qs = new StringBuilder(); + qs.append("select distinct p from Product as p "); + qs.append("join fetch p.merchantStore merch "); + qs.append("join fetch p.availabilities pa "); + qs.append("left join fetch pa.prices pap "); + qs.append("left join fetch pap.descriptions papd "); + + qs.append("left join fetch p.descriptions pd "); + qs.append("left join fetch p.categories categs "); + qs.append("left join fetch categs.descriptions cd "); + + + // images + qs.append("left join fetch p.images images "); + + // other lefts + qs.append("left join fetch p.manufacturer manuf "); + qs.append("left join fetch manuf.descriptions manufd "); + qs.append("left join fetch p.type type "); + qs.append("left join fetch p.taxClass tx "); + + // RENTAL + //qs.append("left join fetch p.owner owner "); + + /**/ + // attributes + if (criteria.getOrigin().equals(ProductCriteria.ORIGIN_SHOP) + && !CollectionUtils.isEmpty(criteria.getAttributeCriteria())) { + qs.append(" inner join p.attributes pattr"); + qs.append(" inner join pattr.productOption po"); + qs.append(" inner join po.descriptions pod"); + qs.append(" inner join pattr.productOptionValue pov "); + qs.append(" inner join pov.descriptions povd"); + } else if(criteria.getOrigin().equals(ProductCriteria.ORIGIN_SHOP)) { + qs.append(" left join fetch p.attributes pattr"); + qs.append(" left join fetch pattr.productOption po"); + /** prevent full table scan **/ + qs.append(" left join fetch po.descriptions pod"); + qs.append(" left join fetch pattr.productOptionValue pov"); + qs.append(" left join fetch pov.descriptions povd"); + } + + /** + * variants + */ + if(criteria.getOrigin().equals(ProductCriteria.ORIGIN_SHOP)) { + qs.append(" left join fetch p.variants pinst "); + qs.append(" left join fetch pinst.variation pv "); + qs.append( "left join fetch pv.productOption pvpo "); + qs.append(" left join fetch pv.productOptionValue pvpov "); + qs.append(" left join fetch pvpo.descriptions pvpod "); + qs.append(" left join fetch pvpov.descriptions pvpovd "); + + qs.append(" left join fetch pinst.variationValue pvv "); + qs.append(" left join fetch pvv.productOption pvvpo "); + qs.append(" left join fetch pvv.productOptionValue pvvpov "); + qs.append(" left join fetch pvvpo.descriptions povvpod "); + qs.append(" left join fetch pvpov.descriptions povvpovd "); + + //variant availability and price + qs.append(" left join fetch pinst.availabilities pinsta "); + qs.append(" left join fetch pinsta.prices pinstap "); + qs.append(" left join fetch pinstap.descriptions pinstapdesc "); + qs.append(" left join fetch pinst.productVariantGroup pinstg "); + qs.append(" left join fetch pinstg.images pinstgimg "); + qs.append(" left join fetch pinstgimg.descriptions "); + //end variants + } + + /** not required at list level **/ + //qs.append(" left join fetch p.relationships pr"); + + qs.append(" where merch.id=:mId"); + if (criteria.getLanguage() != null && !criteria.getLanguage().equals("_all")) { + qs.append(" and pd.language.code=:lang"); + } + + if (!CollectionUtils.isEmpty(criteria.getProductIds())) { + qs.append(" and p.id in (:pId)"); + } + + if (!CollectionUtils.isEmpty(criteria.getCategoryIds())) { + qs.append(" and categs.id in (:cid)"); + } + + + if (criteria.getManufacturerId() != null) { + qs.append(" and manuf.id = :manufid"); + } + + if (criteria.getAvailable() != null) { + if (criteria.getAvailable()) { + qs.append(" and p.available=true and p.dateAvailable<=:dt"); + } else { + qs.append(" and p.available=false and p.dateAvailable>:dt"); + } + } + + if (!StringUtils.isBlank(criteria.getProductName())) { + qs.append(" and lower(pd.name) like :nm"); + } + + if (!StringUtils.isBlank(criteria.getCode())) { + qs.append(" and lower(p.sku) like :sku"); + } + + // RENTAL + /** + if (!StringUtils.isBlank(criteria.getStatus())) { + qs.append(" and p.rentalStatus = :status"); + } + **/ + + /** + if (criteria.getOwnerId() != null) { + qs.append(" and owner.id = :ownerid"); + } + **/ + + /**/ + if (criteria.getOrigin().equals(ProductCriteria.ORIGIN_SHOP) + && !CollectionUtils.isEmpty(criteria.getAttributeCriteria())) { + int cnt = 0; + for (AttributeCriteria attributeCriteria : criteria.getAttributeCriteria()) { + qs.append(" and po.code =:").append(attributeCriteria.getAttributeCode()); + qs.append(" and povd.description like :").append("val").append(cnt) + .append(attributeCriteria.getAttributeCode()); + cnt++; + } + if (criteria.getLanguage() != null && !criteria.getLanguage().equals("_all")) { + qs.append(" and povd.language.code=:lang"); + } + + } + + /**/ + if(criteria.getOrigin().equals(ProductCriteria.ORIGIN_SHOP) + && CollectionUtils.isNotEmpty(criteria.getOptionValueIds())) { + qs.append(" and pov.id in (:povid)"); + } + + qs.append(" order by p.sortOrder asc"); + + String hql = qs.toString(); + Query q = this.em.createQuery(hql); + + if (criteria.getLanguage() != null && !criteria.getLanguage().equals("_all")) { + q.setParameter("lang", language.getCode()); + } + q.setParameter("mId", store.getId()); + + if (!CollectionUtils.isEmpty(criteria.getCategoryIds())) { + q.setParameter("cid", criteria.getCategoryIds()); + } + + /**/ + if (criteria.getOrigin().equals(ProductCriteria.ORIGIN_SHOP) + && CollectionUtils.isNotEmpty(criteria.getOptionValueIds())) { + q.setParameter("povid", criteria.getOptionValueIds()); + } + + if (!CollectionUtils.isEmpty(criteria.getProductIds())) { + q.setParameter("pId", criteria.getProductIds()); + } + + if (criteria.getAvailable() != null) { + q.setParameter("dt", new Date()); + } + + if (criteria.getManufacturerId() != null) { + q.setParameter("manufid", criteria.getManufacturerId()); + } + + if (!StringUtils.isBlank(criteria.getCode())) { + q.setParameter("sku", + new StringBuilder().append("%").append(criteria.getCode().toLowerCase()).append("%").toString()); + } + + /**/ + if (criteria.getOrigin().equals(ProductCriteria.ORIGIN_SHOP) + && !CollectionUtils.isEmpty(criteria.getAttributeCriteria())) { + int cnt = 0; + for (AttributeCriteria attributeCriteria : criteria.getAttributeCriteria()) { + q.setParameter(attributeCriteria.getAttributeCode(), attributeCriteria.getAttributeCode()); + q.setParameter("val" + cnt + attributeCriteria.getAttributeCode(), + "%" + attributeCriteria.getAttributeValue() + "%"); + cnt++; + } + } + + // RENTAL + /** + if (!StringUtils.isBlank(criteria.getStatus())) { + q.setParameter("status", criteria.getStatus()); + } + **/ + + /** + if (criteria.getOwnerId() != null) { + q.setParameter("ownerid", criteria.getOwnerId()); + } + **/ + + if (!StringUtils.isBlank(criteria.getProductName())) { + q.setParameter("nm", new StringBuilder().append("%").append(criteria.getProductName().toLowerCase()) + .append("%").toString()); + } + + @SuppressWarnings("rawtypes") + GenericEntityList entityList = new GenericEntityList(); + entityList.setTotalCount(count.intValue()); + + q = RepositoryHelper.paginateQuery(q, count, entityList, criteria); + + + @SuppressWarnings("unchecked") + List products = q.getResultList(); + productList.setProducts(products); + + return productList; + + } + + @Override + public List listByStore(MerchantStore store) { + + /** + * Testing in debug mode takes a long time with this query running in + * normal mode is fine + */ + + StringBuilder qs = new StringBuilder(); + qs.append("select p from Product as p "); + qs.append("join fetch p.merchantStore merch "); + qs.append("join fetch p.availabilities pa "); + qs.append("left join fetch pa.prices pap "); + + qs.append("join fetch p.descriptions pd "); + qs.append("left join fetch p.categories categs "); + + qs.append("left join fetch pap.descriptions papd "); + + // images + qs.append("left join fetch p.images images "); + + // options (do not need attributes for listings) + qs.append("left join fetch p.attributes pattr "); + qs.append("left join fetch pattr.productOption po "); + qs.append("left join fetch po.descriptions pod "); + qs.append("left join fetch pattr.productOptionValue pov "); + qs.append("left join fetch pov.descriptions povd "); + + // other lefts + qs.append("left join fetch p.manufacturer manuf "); + qs.append("left join fetch manuf.descriptions manufd "); + qs.append("left join fetch p.type type "); + qs.append("left join fetch p.taxClass tx "); + + // RENTAL + //qs.append("left join fetch p.owner owner "); + + // qs.append("where pa.region in (:lid) "); + qs.append("where merch.id=:mid"); + + String hql = qs.toString(); + Query q = this.em.createQuery(hql); + + q.setParameter("mid", store.getId()); + + @SuppressWarnings("unchecked") + List products = q.getResultList(); + + return products; + + } + + @Override + public List listByTaxClass(TaxClass taxClass) { + + /** + * Testing in debug mode takes a long time with this query running in + * normal mode is fine + */ + + StringBuilder qs = new StringBuilder(); + qs.append("select p from Product as p "); + qs.append("join fetch p.merchantStore merch "); + qs.append("join fetch p.availabilities pa "); + qs.append("left join fetch pa.prices pap "); + + qs.append("join fetch p.descriptions pd "); + qs.append("join fetch p.categories categs "); + + qs.append("left join fetch pap.descriptions papd "); + + // images + qs.append("left join fetch p.images images "); + + // options (do not need attributes for listings) + qs.append("left join fetch p.attributes pattr "); + qs.append("left join fetch pattr.productOption po "); + qs.append("left join fetch po.descriptions pod "); + qs.append("left join fetch pattr.productOptionValue pov "); + qs.append("left join fetch pov.descriptions povd "); + + // other lefts + qs.append("left join fetch p.manufacturer manuf "); + qs.append("left join fetch manuf.descriptions manufd "); + qs.append("left join fetch p.type type "); + qs.append("left join fetch p.taxClass tx "); + + // RENTAL + //qs.append("left join fetch p.owner owner "); + + // qs.append("where pa.region in (:lid) "); + qs.append("where tx.id=:tid"); + + String hql = qs.toString(); + Query q = this.em.createQuery(hql); + + q.setParameter("tid", taxClass.getId()); + + @SuppressWarnings("unchecked") + List products = q.getResultList(); + + return products; + + } + + @Deprecated + private String productQueryV1() { + + StringBuilder qs = new StringBuilder(); + qs.append("select distinct p from Product as p "); + qs.append("join fetch p.availabilities pa "); + qs.append("join fetch p.merchantStore merch "); + qs.append("join fetch p.descriptions pd "); + + qs.append("left join fetch p.categories categs "); + qs.append("left join fetch categs.descriptions categsd "); + + qs.append("left join fetch pa.prices pap "); + qs.append("left join fetch pap.descriptions papd "); + + // images + qs.append("left join fetch p.images images "); + // options + qs.append("left join fetch p.attributes pattr "); + qs.append("left join fetch pattr.productOption po "); + qs.append("left join fetch po.descriptions pod "); + qs.append("left join fetch pattr.productOptionValue pov "); + qs.append("left join fetch pov.descriptions povd "); + + //relations + qs.append("left join fetch p.relationships pr "); + + // variants + //qs.append("left join fetch pa.variants pav "); + //qs.append("left join fetch pav.attribute pavattr "); + + // other lefts + qs.append("left join fetch p.manufacturer manuf "); + qs.append("left join fetch manuf.descriptions manufd "); + qs.append("left join fetch p.type type "); + qs.append("left join fetch p.taxClass tx "); + + // RENTAL REMOVED + //qs.append("left join fetch p.owner owner "); + return qs.toString(); + + } + + private String productQueryV2() { + StringBuilder qs = new StringBuilder(); + qs.append("select distinct p from Product as p "); + qs.append("join fetch p.descriptions pd "); + qs.append("join fetch p.merchantStore merch "); + qs.append("left join fetch p.availabilities pavail "); + qs.append("left join fetch p.type type "); + // images + qs.append("left join fetch p.images images "); + qs.append("left join fetch pavail.prices pavailpr "); + qs.append("left join fetch pavailpr.descriptions pavailprdesc "); + + qs.append("left join fetch p.categories categs "); + qs.append("left join fetch categs.descriptions categsd "); + + // options + qs.append("left join fetch p.attributes pattr "); + qs.append("left join fetch pattr.productOption po "); + qs.append("left join fetch po.descriptions pod "); + qs.append("left join fetch pattr.productOptionValue pov "); + qs.append("left join fetch pov.descriptions povd "); + qs.append("left join fetch p.relationships pr "); + // other lefts + qs.append("left join fetch p.manufacturer manuf "); + qs.append("left join fetch manuf.descriptions manufd "); + qs.append("left join fetch p.type type "); + + //variants + qs.append("left join fetch p.variants pinst "); + qs.append("left join fetch pinst.variation pv "); + qs.append("left join fetch pv.productOption pvpo "); + qs.append("left join fetch pv.productOptionValue pvpov "); + qs.append("left join fetch pvpo.descriptions pvpod "); + qs.append("left join fetch pvpov.descriptions pvpovd "); + + qs.append("left join fetch pinst.variationValue pvv "); + qs.append("left join fetch pvv.productOption pvvpo "); + qs.append("left join fetch pvv.productOptionValue pvvpov "); + qs.append("left join fetch pvvpo.descriptions povvpod "); + qs.append("left join fetch pvpov.descriptions povvpovd "); + + //variant availability and price + qs.append("left join fetch pinst.availabilities pinsta "); + qs.append("left join fetch pinsta.prices pinstap "); + qs.append("left join fetch pinstap.descriptions pinstapdesc "); + qs.append("left join fetch pinst.productVariantGroup pinstg "); + qs.append("left join fetch pinstg.images pinstgimg "); + qs.append("left join fetch pinstgimg.descriptions "); + //end variants + + return qs.toString(); + } + + + + @Override + public Product getById(Long id, MerchantStore store, Language language) { + + try { + + StringBuilder qs = new StringBuilder(); + qs.append("select distinct p from Product as p "); + qs.append("join fetch p.descriptions pd "); + qs.append("join fetch p.merchantStore pm "); + qs.append("left join fetch p.availabilities pavail "); + qs.append("left join fetch p.type type "); + qs.append("left join fetch pavail.prices pavailpr "); + qs.append("left join fetch pavailpr.descriptions pavailprdesc "); + + qs.append("left join fetch p.categories categs "); + qs.append("left join fetch categs.descriptions categsd "); + + // options + qs.append("left join fetch p.attributes pattr "); + qs.append("left join fetch pattr.productOption po "); + qs.append("left join fetch po.descriptions pod "); + qs.append("left join fetch pattr.productOptionValue pov "); + qs.append("left join fetch pov.descriptions povd "); + qs.append("left join fetch p.relationships pr "); + // other lefts + qs.append("left join fetch p.manufacturer manuf "); + qs.append("left join fetch manuf.descriptions manufd "); + qs.append("left join fetch p.type type "); + + //variants + qs.append("left join fetch p.variants pinst "); + qs.append("left join fetch pinst.variation pv "); + qs.append("left join fetch pv.productOption pvpo "); + qs.append("left join fetch pv.productOptionValue pvpov "); + qs.append("left join fetch pvpo.descriptions pvpod "); + qs.append("left join fetch pvpov.descriptions pvpovd "); + + qs.append("left join fetch pinst.variationValue pvv "); + qs.append("left join fetch pvv.productOption pvvpo "); + qs.append("left join fetch pvv.productOptionValue pvvpov "); + qs.append("left join fetch pvvpo.descriptions povvpod "); + qs.append("left join fetch pvpov.descriptions povvpovd "); + + //variant availability and price + qs.append("left join fetch pinst.availabilities pinsta "); + qs.append("left join fetch pinsta.prices pinstap "); + qs.append("left join fetch pinstap.descriptions pinstapdesc "); + qs.append("left join fetch pinst.productVariantGroup pinstg "); + qs.append("left join fetch pinstg.images pinstgimg "); + qs.append("left join fetch pinstgimg.descriptions "); + //end variants + + qs.append("where p.id=:productId and pm.id=:id"); + + String hql = qs.toString(); + Query q = this.em.createQuery(hql); + + q.setParameter("productId", id); + q.setParameter("id", store.getId()); + + return (Product) q.getSingleResult(); + + } catch (javax.persistence.NoResultException ers) { + return null; + } + + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/PageableProductAttributeRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/PageableProductAttributeRepository.java new file mode 100644 index 0000000000..3f9a7784fa --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/PageableProductAttributeRepository.java @@ -0,0 +1,43 @@ +package com.salesmanager.core.business.repositories.catalog.product.attribute; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; + +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; + +public interface PageableProductAttributeRepository extends PagingAndSortingRepository { + + @Query(value = "select distinct p from ProductAttribute p " + + "join fetch p.product pr " + + "left join fetch p.productOption po " + + "left join fetch p.productOptionValue pov " + + "left join fetch po.descriptions pod " + + "left join fetch pov.descriptions povd " + + "left join fetch po.merchantStore pom " + + "where pom.id = ?1 and pr.id = ?2 and povd.language.id = ?3", + countQuery = "select count(p) " + + "from ProductAttribute p " + + "join p.product pr " + + "join pr.merchantStore pm " + + "where pm.id = ?1 and pr.id = ?2") + Page findByProductId(Integer storeId, Long productId, Integer languageId, Pageable pageable); + + @Query(value = "select distinct p from ProductAttribute p " + + "join fetch p.product pr " + + "left join fetch p.productOption po " + + "left join fetch p.productOptionValue pov " + + "left join fetch po.descriptions pod " + + "left join fetch pov.descriptions povd " + + "left join fetch po.merchantStore pom " + + "where pom.id = ?1 and pr.id = ?2", + countQuery = "select count(p) " + + "from ProductAttribute p " + + "join p.product pr " + + "join pr.merchantStore pm " + + "where pm.id = ?1 and pr.id = ?2") + Page findByProductId(Integer storeId, Long productId, Pageable pageable); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/PageableProductOptionRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/PageableProductOptionRepository.java new file mode 100644 index 0000000000..b0b13b905c --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/PageableProductOptionRepository.java @@ -0,0 +1,16 @@ +package com.salesmanager.core.business.repositories.catalog.product.attribute; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; + +public interface PageableProductOptionRepository extends PagingAndSortingRepository { + + @Query(value = "select distinct p from ProductOption p join fetch p.merchantStore pm left join fetch p.descriptions pd where pm.id = ?1 and (?2 is null or pd.name like %?2%)", + countQuery = "select count(p) from ProductOption p join p.merchantStore pm left join p.descriptions pd where pm.id = ?1 and (?2 is null or pd.name like %?2%)") + Page listOptions(int merchantStoreId, String name, Pageable pageable); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/PageableProductOptionValueRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/PageableProductOptionValueRepository.java new file mode 100644 index 0000000000..50a411de4a --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/PageableProductOptionValueRepository.java @@ -0,0 +1,17 @@ +package com.salesmanager.core.business.repositories.catalog.product.attribute; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; + +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; + +public interface PageableProductOptionValueRepository extends PagingAndSortingRepository { + + @Query(value = "select distinct p from ProductOptionValue p join fetch p.merchantStore pm left join fetch p.descriptions pd where pm.id = ?1 and (?2 is null or (pd.name like %?2% or p.code like %?2%))", + countQuery = "select count(p) from ProductOptionValue p join p.merchantStore pm left join p.descriptions pd where pm.id = ?1 and (?2 is null or (pd.name like %?2% or p.code like %?2%))") + Page listOptionValues(int merchantStoreId, String name, Pageable pageable); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/ProductAttributeRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/ProductAttributeRepository.java new file mode 100755 index 0000000000..13ef1f5f5d --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/ProductAttributeRepository.java @@ -0,0 +1,36 @@ +package com.salesmanager.core.business.repositories.catalog.product.attribute; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; + +public interface ProductAttributeRepository extends JpaRepository { + + @Query("select p from ProductAttribute p join fetch p.product pr left join fetch p.productOption po left join fetch p.productOptionValue pov left join fetch po.descriptions pod left join fetch pov.descriptions povd left join fetch po.merchantStore where p.id = ?1") + ProductAttribute findOne(Long id); + + @Query("select p from ProductAttribute p join fetch p.product pr left join fetch p.productOption po left join fetch p.productOptionValue pov left join fetch po.descriptions pod left join fetch pov.descriptions povd left join fetch po.merchantStore pom where pom.id = ?1 and po.id = ?2") + List findByOptionId(Integer storeId, Long id); + + @Query("select distinct p from ProductAttribute p join fetch p.product pr left join fetch p.productOption po left join fetch p.productOptionValue pov left join fetch po.descriptions pod left join fetch pov.descriptions povd left join fetch po.merchantStore pom where pom.id = ?1 and po.id = ?2") + List findByOptionValueId(Integer storeId, Long id); + + @Query("select distinct p from ProductAttribute p " + + "join fetch p.product pr " + + "left join fetch p.productOption po " + + "left join fetch p.productOptionValue pov " + + "left join fetch po.descriptions pod " + + "left join fetch pov.descriptions povd " + + "left join fetch pov.merchantStore povm " + + "where povm.id = ?1 and pr.id = ?2 and p.id in ?3") + List findByAttributeIds(Integer storeId, Long productId, List ids); + + @Query("select distinct p from ProductAttribute p join fetch p.product pr left join fetch p.productOption po left join fetch p.productOptionValue pov left join fetch po.descriptions pod left join fetch pov.descriptions povd left join fetch po.merchantStore pom where pom.id = ?1") + List findByProductId(Integer storeId, Long productId); + + @Query(value="select distinct p from ProductAttribute p join fetch p.product pr left join fetch pr.categories prc left join fetch p.productOption po left join fetch p.productOptionValue pov left join fetch po.descriptions pod left join fetch pov.descriptions povd left join fetch po.merchantStore pom where pom.id = ?1 and prc.id IN (select c.id from Category c where c.lineage like ?2% and povd.language.id = ?3)") + List findOptionsByCategoryLineage(Integer storeId, String lineage, Integer languageId); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/ProductOptionRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/ProductOptionRepository.java new file mode 100755 index 0000000000..5adaacb6e8 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/ProductOptionRepository.java @@ -0,0 +1,31 @@ +package com.salesmanager.core.business.repositories.catalog.product.attribute; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; + +public interface ProductOptionRepository extends JpaRepository { + + @Query("select p from ProductOption p join fetch p.merchantStore pm left join fetch p.descriptions pd where p.id = ?1") + ProductOption findOne(Long id); + + @Query("select p from ProductOption p join fetch p.merchantStore pm left join fetch p.descriptions pd where p.id = ?2 and pm.id = ?1") + ProductOption findOne(Integer storeId, Long id); + + @Query("select distinct p from ProductOption p join fetch p.merchantStore pm left join fetch p.descriptions pd where pm.id = ?1 and pd.language.id = ?2") + List findByStoreId(Integer storeId, Integer languageId); + + @Query("select p from ProductOption p join fetch p.merchantStore pm left join fetch p.descriptions pd where pm.id = ?1 and pd.name like %?2% and pd.language.id = ?3") + List findByName(Integer storeId, String name, Integer languageId); + + @Query("select p from ProductOption p join fetch p.merchantStore pm left join fetch p.descriptions pd where pm.id = ?1 and p.code = ?2") + ProductOption findByCode(Integer storeId, String optionCode); + + @Query("select distinct p from ProductOption p join fetch p.merchantStore pm left join fetch p.descriptions pd where pm.id = ?1 and p.code = ?2 and p.readOnly = ?3") + List findByReadOnly(Integer storeId, Integer languageId, boolean readOnly); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/ProductOptionSetRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/ProductOptionSetRepository.java new file mode 100644 index 0000000000..a2f7c4f0ec --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/ProductOptionSetRepository.java @@ -0,0 +1,29 @@ +package com.salesmanager.core.business.repositories.catalog.product.attribute; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionSet; + +public interface ProductOptionSetRepository extends JpaRepository { + + @Query("select distinct p from ProductOptionSet p join fetch p.store pm left join fetch p.option po left join fetch po.descriptions pod left join fetch p.values pv left join fetch pv.descriptions pvd where pm.id = ?1 and p.id = ?2 and pod.language.id = ?3") + ProductOptionSet findOne(Integer storeId, Long id, Integer language); + + @Query("select distinct p from ProductOptionSet p join fetch p.store pm left join fetch p.option po left join fetch po.descriptions pod left join fetch p.values pv left join fetch pv.descriptions pvd where pm.id = ?1 and pod.language.id = ?2") + List findByStore(Integer storeId, Integer language); + + @Query("select distinct p from ProductOptionSet p " + + "join fetch p.store pm left join fetch p.productTypes pt " + + "left join fetch p.option po " + + "left join fetch po.descriptions pod " + + "left join fetch p.values pv " + + "left join fetch pv.descriptions pvd where pt.id= ?1 and pm.id = ?2 and pod.language.id = ?3") + List findByProductType(Long typeId, Integer storeId, Integer language); + + @Query("select p from ProductOptionSet p join fetch p.store pm left join fetch p.option po left join fetch po.descriptions pod left join fetch p.values pv left join fetch pv.descriptions pvd where pm.id = ?1 and p.code = ?2") + ProductOptionSet findByCode(Integer storeId, String code); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/ProductOptionValueRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/ProductOptionValueRepository.java new file mode 100755 index 0000000000..52b6cf6b02 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/attribute/ProductOptionValueRepository.java @@ -0,0 +1,30 @@ +package com.salesmanager.core.business.repositories.catalog.product.attribute; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; + +public interface ProductOptionValueRepository extends JpaRepository { + + @Query("select p from ProductOptionValue p join fetch p.merchantStore pm left join fetch p.descriptions pd where p.id = ?1") + ProductOptionValue findOne(Long id); + + @Query("select p from ProductOptionValue p join fetch p.merchantStore pm left join fetch p.descriptions pd where p.id = ?2 and pm.id = ?1") + ProductOptionValue findOne(Integer storeId, Long id); + + @Query("select distinct p from ProductOptionValue p join fetch p.merchantStore pm left join fetch p.descriptions pd where pm.id = ?1 and pd.language.id = ?2") + List findByStoreId(Integer storeId, Integer languageId); + + @Query("select p from ProductOptionValue p join fetch p.merchantStore pm left join fetch p.descriptions pd where pm.id = ?1 and p.code = ?2") + ProductOptionValue findByCode(Integer storeId, String optionValueCode); + + @Query("select p from ProductOptionValue p join fetch p.merchantStore pm left join fetch p.descriptions pd where pm.id = ?1 and (pd.name like %?2% or p.code like %?2%) and pd.language.id = ?3") + List findByName(Integer storeId, String name, Integer languageId); + + @Query("select distinct p from ProductOptionValue p join fetch p.merchantStore pm left join fetch p.descriptions pd where pm.id = ?1 and pd.language.id = ?2 and p.productOptionDisplayOnly = ?3") + List findByReadOnly(Integer storeId, Integer languageId, boolean readOnly); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/availability/PageableProductAvailabilityRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/availability/PageableProductAvailabilityRepository.java new file mode 100644 index 0000000000..d4b5946cad --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/availability/PageableProductAvailabilityRepository.java @@ -0,0 +1,65 @@ +package com.salesmanager.core.business.repositories.catalog.product.availability; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; + +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; + +public interface PageableProductAvailabilityRepository extends PagingAndSortingRepository { + + @Query(value = "select distinct p from ProductAvailability p " + "left join fetch p.merchantStore pm " + + "left join fetch p.prices pp " + "left join fetch pp.descriptions ppd " + "join fetch p.product ppr " + + "left join fetch ppr.merchantStore pprm " + "where ppr.id=?1 " + "and pprm.id=?2 " + + "and (?3 is null or pm.code like %?3%)", countQuery = "select count(p) from ProductAvailability p " + + "join p.merchantStore pm " + "join p.prices pp " + "join pp.descriptions ppd " + + "join p.merchantStore pm " + "join p.product ppr " + "join ppr.merchantStore pprm " + + "where ppr.id=?1 " + "and pprm.id=?2 " + "and (?3 is null or pm.code like %?3%)") + Page listByStore(Long productId, Integer storeId, String child, Pageable pageable); + + @Query(value = "select distinct p from ProductAvailability p " + "left join fetch p.merchantStore pm " + + "left join fetch p.prices pp " + "left join fetch pp.descriptions ppd " + "join fetch p.product ppr " + + "left join fetch ppr.merchantStore pprm " + + "where pm.id=?1 ", countQuery = "select count(p) from ProductAvailability p " + + "join p.merchantStore pm " + "where pm.id=?1 ") + Page listByStore(Integer storeId, Pageable pageable); + + @Query(value = "select distinct p from ProductAvailability p " + "left join fetch p.merchantStore pm " + + "left join fetch p.prices pp " + + "left join fetch pp.descriptions ppd " + + "join fetch p.product ppr " + + "join fetch ppr.merchantStore pprm " + + "left join fetch ppr.variants ppri " + + "left join fetch ppri.availabilities ppria " + + "left join fetch ppria.prices ppriap " + + "left join fetch ppriap.descriptions ppriapd " + + "where ppr.id=?1 and pm.code=?2", countQuery = "select count(p) from ProductAvailability p " + + "join p.merchantStore pm " + "join p.product ppr left join ppr.variants ppri left join ppri.availabilities ppria " + "where ppr.id=?1 " + + "and pm.code=?2") + Page getByProductId(Long productId, String store, Pageable pageable); + + @Query(value = "select distinct p from ProductAvailability p " + "left join fetch p.merchantStore pm " + + "left join fetch p.prices pp " + + "left join fetch pp.descriptions ppd " + + "join fetch p.product ppr " + + "left join fetch p.productVariant ppi " + + "where ppr.sku=?1 or ppi.sku=?1 " + + "and pm.code=?2", countQuery = "select count(p) from ProductAvailability p " + "join p.merchantStore pm " + + "join p.product ppr " + "left join p.productVariant ppi " + "where ppr.sku=?1 or ppi.sku=?1 " + + "and pm.code=?2") + Page getBySku(String productCode, String store, Pageable pageable); + + @Query(value = "select distinct p from ProductAvailability p " + + "left join fetch p.merchantStore pm " + + "left join fetch p.prices pp " + + "left join fetch pp.descriptions ppd " + "join fetch p.product ppr " + + "left join fetch p.productVariant ppi " + + "where ppr.sku=?1 or ppi.sku=?1", countQuery = "select count(p) from ProductAvailability p " + + "join p.merchantStore pm " + "join p.product ppr " + "left join p.productVariant ppi " + + "where ppr.sku=?1 or ppi.sku=?1 ") + Page getBySku(String productCode, Pageable pageable); + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/availability/ProductAvailabilityRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/availability/ProductAvailabilityRepository.java new file mode 100755 index 0000000000..12d7d247e9 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/availability/ProductAvailabilityRepository.java @@ -0,0 +1,56 @@ +package com.salesmanager.core.business.repositories.catalog.product.availability; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; + +public interface ProductAvailabilityRepository extends JpaRepository { + + + @Query(value = "select distinct p from ProductAvailability p " + + "left join fetch p.merchantStore pm " + + "left join fetch p.prices pp " + + "left join fetch pp.descriptions ppd " + + "left join fetch p.merchantStore pm " + + "join fetch p.product ppr " + + "join fetch ppr.merchantStore pprm " + + "where p.id=?1 ") + ProductAvailability getById(Long availabilityId); + + @Query(value = "select distinct p from ProductAvailability p " + + "left join fetch p.merchantStore pm " + + "left join fetch p.prices pp " + + "left join fetch pp.descriptions ppd " + + "left join fetch p.merchantStore pm " + + "join fetch p.product ppr " + + "join fetch ppr.merchantStore pprm " + + "where p.id=?1 " + + "and pprm.id=?2") + ProductAvailability getById(Long availabilityId, int merchantId); + + + @Query(value = "select distinct p from ProductAvailability p " + + "left join fetch p.merchantStore pm " + + "left join fetch p.prices pp " + + "left join fetch pp.descriptions ppd " + + "join fetch p.product ppr " + + "left join fetch ppr.descriptions pprd " + + "left join fetch p.productVariant ppi " + + "where ppr.sku=?1 or ppi.sku=?1 " + + "and pm.code=?2") + List getBySku(String productCode, String store); + + @Query(value = "select distinct p from ProductAvailability p " + + "left join fetch p.merchantStore pm " + + "left join fetch p.prices pp " + + "left join fetch pp.descriptions ppd " + + "join fetch p.product ppr " + + "left join fetch ppr.descriptions pprd " + + "left join fetch p.productVariant ppi " + + "where ppr.sku=?1 or ppi.sku=?1") + List getBySku(String sku); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/file/DigitalProductRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/file/DigitalProductRepository.java new file mode 100755 index 0000000000..ccfeb469fc --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/file/DigitalProductRepository.java @@ -0,0 +1,17 @@ +package com.salesmanager.core.business.repositories.catalog.product.file; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.product.file.DigitalProduct; + +public interface DigitalProductRepository extends JpaRepository { + + @Query("select p from DigitalProduct p inner join fetch p.product pp inner join fetch pp.merchantStore ppm where ppm.id =?1 and pp.id = ?2") + DigitalProduct findByProduct(Integer storeId, Long productId); + + @Query("select p from DigitalProduct p inner join fetch p.product pp inner join fetch pp.merchantStore ppm where p.id = ?1") + DigitalProduct findOne(Long id); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/image/ProductImageRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/image/ProductImageRepository.java new file mode 100755 index 0000000000..0f63b1c187 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/image/ProductImageRepository.java @@ -0,0 +1,18 @@ +package com.salesmanager.core.business.repositories.catalog.product.image; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.product.image.ProductImage; + +public interface ProductImageRepository extends JpaRepository { + + + @Query("select p from ProductImage p left join fetch p.descriptions pd inner join fetch p.product pp inner join fetch pp.merchantStore ppm where p.id = ?1") + ProductImage findOne(Long id); + + @Query("select p from ProductImage p left join fetch p.descriptions pd inner join fetch p.product pp inner join fetch pp.merchantStore ppm where pp.id = ?2 and ppm.code = ?3 and p.id = ?1") + ProductImage finById(Long imageId, Long productId, String storeCode); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/manufacturer/ManufacturerRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/manufacturer/ManufacturerRepository.java new file mode 100755 index 0000000000..7210403b93 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/manufacturer/ManufacturerRepository.java @@ -0,0 +1,45 @@ +package com.salesmanager.core.business.repositories.catalog.product.manufacturer; + +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; + +public interface ManufacturerRepository extends JpaRepository { + + @Query("select count(distinct p) from Product as p where p.manufacturer.id=?1") + Long countByProduct(Long manufacturerId); + + @Query("select m from Manufacturer m left join fetch m.descriptions md join fetch m.merchantStore ms where ms.id=?1 and md.language.id=?2") + List findByStoreAndLanguage(Integer storeId, Integer languageId); + + @Query("select m from Manufacturer m left join fetch m.descriptions md join fetch m.merchantStore ms where m.id=?1") + Manufacturer findOne(Long id); + + @Query("select m from Manufacturer m left join fetch m.descriptions md join fetch m.merchantStore ms where ms.id=?1") + List findByStore(Integer storeId); + + @Query("select m from Manufacturer m join fetch m.descriptions md join fetch m.merchantStore ms join fetch md.language mdl where ms.id=?1 and mdl.id=?2 and (?3 is null or md.name like %?3%)") + //@Query("select m from Manufacturer m join fetch m.descriptions md join fetch m.merchantStore ms join fetch md.language mdl where ms.id=?1 and mdl.id=?2") + //@Query("select m from Manufacturer m left join m.descriptions md join fetch m.merchantStore ms where ms.id=?1") + List findByStore(Integer storeId, Integer languageId, String name); + + + @Query("select distinct manufacturer from Product as p join p.manufacturer manufacturer join manufacturer.descriptions md join p.categories categs where categs.id in (?1) and md.language.id=?2") + List findByCategoriesAndLanguage(List categoryIds, Integer languageId); + + @Query("select m from Manufacturer m left join m.descriptions md join fetch m.merchantStore ms where m.code=?1 and ms.id=?2") + Manufacturer findByCodeAndMerchandStore(String code, Integer storeId); + + @Query("select count(distinct m) from Manufacturer as m where m.merchantStore.id=?1") + int count(Integer storeId); + + @Query(value="select distinct manufacturer from Product as p " + + "join p.manufacturer manufacturer " + + "left join manufacturer.descriptions pmd " + + "join fetch manufacturer.merchantStore pms " + + "join p.categories pc " + + "where pms.id = ?1 " + + "and pc.id IN (select c.id from Category c where c.lineage like %?2% and pmd.language.id = ?3)") + List findByProductInCategoryId(Integer storeId, String lineage, Integer languageId); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/manufacturer/PageableManufacturerRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/manufacturer/PageableManufacturerRepository.java new file mode 100644 index 0000000000..7db498107e --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/manufacturer/PageableManufacturerRepository.java @@ -0,0 +1,18 @@ +package com.salesmanager.core.business.repositories.catalog.product.manufacturer; + +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; + +public interface PageableManufacturerRepository extends PagingAndSortingRepository { + + @Query("select m from Manufacturer m left join m.descriptions md inner join m.merchantStore ms where ms.id=?1 and md.language.id=?2 and (?3 is null or md.name like %?3%)") + Page findByStore(Integer storeId, Integer languageId, String name, Pageable pageable); + + @Query("select m from Manufacturer m left join m.descriptions md inner join m.merchantStore ms where ms.id=?1 and (?2 is null or md.name like %?2%)") + Page findByStore(Integer storeId, String name, Pageable pageable); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/price/ProductPriceRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/price/ProductPriceRepository.java new file mode 100755 index 0000000000..c33a9c08c7 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/price/ProductPriceRepository.java @@ -0,0 +1,50 @@ +package com.salesmanager.core.business.repositories.catalog.product.price; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.product.price.ProductPrice; + +public interface ProductPriceRepository extends JpaRepository { + + @Query("select p from ProductPrice p " + "left join fetch p.descriptions pd " + + "inner join fetch p.productAvailability pa " + "inner join fetch pa.product pap " + + "inner join fetch pap.merchantStore papm " + "where p.id = ?1") + ProductPrice findOne(Long id); + + // SELECT distinct pp.PRODUCT_PRICE_AMOUNT, p.SKU + // FROM SALESMANAGER.PRODUCT_PRICE AS pp + // INNER JOIN SALESMANAGER.PRODUCT_AVAILABILITY AS pa ON pa.PRODUCT_AVAIL_ID = + // pp.PRODUCT_AVAIL_ID + // INNER JOIN SALESMANAGER.PRODUCT AS p ON p.PRODUCT_ID = pa.PRODUCT_ID + // INNER JOIN SALESMANAGER.PRODUCT_CATEGORY AS pc on p.PRODUCT_ID = + // pc.PRODUCT_ID + // WHERE pc.CATEGORY_ID = 1 + // ORDER BY pp.PRODUCT_PRICE_AMOUNT; + + // @Query("select p from ProductPrice p join fetch p.productAvailability pd + // inner join fetch p.productAvailability pa inner join fetch pa.product pap + // inner join fetch pap.merchantStore papm where p.id = ?1") + // List priceListByCategory(Long id, Integer storeId); + + @Query(value = "select distinct p from ProductPrice p " + "left join fetch p.productAvailability pa " + + "left join fetch pa.merchantStore pm " + "left join fetch p.descriptions pd " + + "join fetch pa.product pap " + "left join fetch pa.productVariant ppi " + + "where pap.sku=?1 or ppi.sku=?1 and pm.code=?2") + List findByProduct(String sku, String store); + + @Query(value = "select distinct p from ProductPrice p " + "left join fetch p.productAvailability pa " + + "left join fetch pa.merchantStore pm " + "left join fetch p.descriptions pd " + + "join fetch pa.product pap " + "left join fetch pa.productVariant ppi " + + "where pap.sku=?1 or ppi.sku=?1 and p.id=?2 and pm.code=?3") + ProductPrice findByProduct(String sku, Long priceId, String store); + + @Query(value = "select distinct p from ProductPrice p " + "left join fetch p.productAvailability pa " + + "left join fetch pa.merchantStore pm " + "left join fetch p.descriptions pd " + + "join fetch pa.product pap " + "left join fetch pa.productVariant ppi " + + "where pap.sku=?1 or ppi.sku=?1 and pa.id=?2 and pm.code=?3") + List findByProductInventoty(String sku, Long ProductInventory, String store); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/relationship/ProductRelationshipRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/relationship/ProductRelationshipRepository.java new file mode 100755 index 0000000000..ce28f74848 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/relationship/ProductRelationshipRepository.java @@ -0,0 +1,10 @@ +package com.salesmanager.core.business.repositories.catalog.product.relationship; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.salesmanager.core.model.catalog.product.relationship.ProductRelationship; + + +public interface ProductRelationshipRepository extends JpaRepository, ProductRelationshipRepositoryCustom { + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/relationship/ProductRelationshipRepositoryCustom.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/relationship/ProductRelationshipRepositoryCustom.java new file mode 100755 index 0000000000..4f1294c185 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/relationship/ProductRelationshipRepositoryCustom.java @@ -0,0 +1,35 @@ +package com.salesmanager.core.business.repositories.catalog.product.relationship; + +import java.util.List; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.relationship.ProductRelationship; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + + +public interface ProductRelationshipRepositoryCustom { + + List getByType(MerchantStore store, String type, + Language language); + + List getByType(MerchantStore store, String type, + Product product, Language language); + + List getByGroup(MerchantStore store, String group); + + List getGroups(MerchantStore store); + + List getByType(MerchantStore store, String type); + + List getGroupByType(MerchantStore store, String type); + + List listByProducts(Product product); + + List getByType(MerchantStore store, String type, + Product product); + + List getByTypeAndRelatedProduct(MerchantStore store, String type, + Product product); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/relationship/ProductRelationshipRepositoryImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/relationship/ProductRelationshipRepositoryImpl.java new file mode 100755 index 0000000000..d3c0beda87 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/relationship/ProductRelationshipRepositoryImpl.java @@ -0,0 +1,220 @@ +package com.salesmanager.core.business.repositories.catalog.product.relationship; + +import com.google.api.client.util.Lists; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.relationship.ProductRelationship; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + + +public class ProductRelationshipRepositoryImpl implements ProductRelationshipRepositoryCustom { + + private static final String HQL_GET_BY_CODE_AND_STORE_ID_AND_PRODUCT_ID = + "select distinct pr from ProductRelationship as pr " + + "left join fetch pr.product p " + + "join fetch pr.relatedProduct rp " + + "left join fetch rp.descriptions rpd " + + "where pr.code=:code " + + "and pr.store.id=:storeId " + + "and p.id=:id " + + "and rpd.language.id=:langId"; + private static final String HQL_GET_BY_CODE_AND_STORE_ID_AND_RP_PRODUCT_ID = + "select distinct pr from ProductRelationship as pr " + + "left join fetch pr.relatedProduct rp " + + "where pr.code=:code " + + "and pr.store.id=:storeId " + + "and rp.available=:available " + + "and rp.id=:rpid"; + private static final String HQL_GET_BY_PRODUCT_ID_AND_CODE_AVAILABLE = + "select distinct pr from ProductRelationship as pr " + + "left join fetch pr.product p " + + "left join fetch pr.relatedProduct rp " + + "left join fetch rp.attributes pattr " + + "left join fetch rp.categories rpc " + + "left join fetch rpc.descriptions rpcd " + + "left join fetch rp.descriptions rpd " + + "left join fetch rp.owner rpo " + + "left join fetch rp.images pd " + + "left join fetch rp.merchantStore rpm " + + "left join fetch rpm.currency rpmc " + + "left join fetch rp.availabilities pa " + + "left join fetch pa.prices pap " + + "left join fetch pap.descriptions papd " + + "left join fetch rp.manufacturer manuf " + + "left join fetch manuf.descriptions manufd " + + "left join fetch rp.type type " + + "where pr.code=:code " + + "and rp.available=:available " + + "and p.id=:pId"; + private static final String HQL_GET_PRODUCTS_BY_PRODUCT_ID = + "select distinct pr from ProductRelationship as pr " + + "left join fetch pr.product p " + + "left join fetch pr.relatedProduct rp " + + "left join fetch rp.attributes pattr " + + "left join fetch rp.categories rpc " + + "left join fetch p.descriptions pd " + + "left join fetch rp.descriptions rpd " + + "where p.id=:id" + + " or rp.id=:id"; + private static final String HQL_GET_PRODUCT_BY_CODE_AND_STORE_ID = + "select distinct pr from ProductRelationship as pr " + + "left join fetch pr.product p " + + "join fetch pr.relatedProduct rp " + + "left join fetch rp.descriptions rpd " + + "where pr.code=:code " + + "and pr.store.id=:storeId "; + private static final String HQL_GET_PRODUCT_BY_CODE_AND_STORE_ID_AND_LANG_ID = + "select distinct pr from ProductRelationship as pr " + + "left join fetch pr.product p " + + "join fetch pr.relatedProduct rp " + + "left join fetch rp.attributes pattr " + + "left join fetch pattr.productOption po " + + "left join fetch po.descriptions pod " + + "left join fetch pattr.productOptionValue pov " + + "left join fetch pov.descriptions povd " + + "left join fetch rp.categories rpc " + + "left join fetch rpc.descriptions rpcd " + + "left join fetch rp.descriptions rpd " + + "left join fetch rp.owner rpo " + + "left join fetch rp.images pd " + + "left join fetch rp.merchantStore rpm " + + "left join fetch rpm.currency rpmc " + + "left join fetch rp.availabilities pa " + + "left join fetch rp.manufacturer m " + + "left join fetch m.descriptions md " + + "left join fetch pa.prices pap " + + "left join fetch pap.descriptions papd " + + "where pr.code=:code " + + "and pr.store.id=:storeId " + + "and rpd.language.id=:langId"; + private static final String HQL_GET_GROUP_BY_CODE_AND_STORE_ID = + "select distinct pr from ProductRelationship as pr " + + "left join fetch pr.product p " + + "left join fetch pr.relatedProduct rp " + + "left join fetch rp.attributes pattr " + + "left join fetch rp.categories rpc " + + "left join fetch rpc.descriptions rpcd " + + "left join fetch rp.descriptions rpd " + + "left join fetch rp.owner rpo " + + "left join fetch rp.images pd " + + "left join fetch rp.merchantStore rpm " + + "left join fetch rpm.currency rpmc " + + "left join fetch rp.availabilities pa " + + "left join fetch pa.prices pap " + + "left join fetch pap.descriptions papd " + + "left join fetch rp.manufacturer manuf " + + "left join fetch manuf.descriptions manufd " + + "left join fetch rp.type type " + + "where pr.code=:code " + + "and pr.store.id=:storeId "; + private static final String HQL_GET_PRODUCT_RELATIONSHIP_BY_STORE_ID = + "select distinct pr from ProductRelationship as pr " + + "where pr.store.id=:store " + + "and pr.product=null"; + private static final String HQL_GET_PRODUCT_RELATIONSHIP_BY_CODE_AND_STORE_ID = + "select distinct pr from ProductRelationship as pr " + + "left join fetch pr.product p " + + "left join fetch pr.relatedProduct rp " + + "left join fetch rp.descriptions rpd " + + "where pr.code=:code " + + "and pr.store.id=:storeId " + + "and rpd.language.id=:langId"; + + @PersistenceContext + private EntityManager entityManager; + + @Override + @SuppressWarnings("unchecked") + public List getByType(MerchantStore store, String type, Product product, + Language language) { + return entityManager.createQuery(HQL_GET_BY_CODE_AND_STORE_ID_AND_PRODUCT_ID) + .setParameter("code", type) + .setParameter("id", product.getId()) + .setParameter("storeId", store.getId()) + .setParameter("langId", language.getId()) + .getResultList(); + } + + @Override + @SuppressWarnings("unchecked") + public List getGroupByType(MerchantStore store, String type) { + return entityManager.createQuery(HQL_GET_PRODUCT_RELATIONSHIP_BY_CODE_AND_STORE_ID) + .setParameter("code", type) + .setParameter("storeId", store.getId()) + .getResultList(); + } + + @Override + @SuppressWarnings("unchecked") + public List getByType(MerchantStore store, String type, Language language) { + return entityManager.createQuery(HQL_GET_PRODUCT_BY_CODE_AND_STORE_ID_AND_LANG_ID) + .setParameter("code", type) + .setParameter("langId", language.getId()) + .setParameter("storeId", store.getId()) + .getResultList(); + } + + @Override + @SuppressWarnings("unchecked") + public List getByGroup(MerchantStore store, String group) { + return entityManager.createQuery(HQL_GET_GROUP_BY_CODE_AND_STORE_ID) + .setParameter("code", group) + .setParameter("storeId", store.getId()) + .getResultList(); + } + + @Override + public List getGroups(MerchantStore store) { + @SuppressWarnings("unchecked") + List relations = entityManager.createQuery(HQL_GET_PRODUCT_RELATIONSHIP_BY_STORE_ID) + .setParameter("store", store.getId()) + .getResultList(); + Map relationMap = relations.stream() + .collect(Collectors.toMap(ProductRelationship::getCode, p -> p, (p, q) -> p)); + return Lists.newArrayList(relationMap.values()); + } + + + @Override + @SuppressWarnings("unchecked") + public List getByType(MerchantStore store, String type) { + return entityManager.createQuery(HQL_GET_PRODUCT_BY_CODE_AND_STORE_ID) + .setParameter("code", type) + .setParameter("storeId", store.getId()) + .getResultList(); + } + + @Override + @SuppressWarnings("unchecked") + public List listByProducts(Product product) { + return entityManager.createQuery(HQL_GET_PRODUCTS_BY_PRODUCT_ID) + .setParameter("id", product.getId()) + .getResultList(); + } + + @Override + @SuppressWarnings("unchecked") + public List getByType(MerchantStore store, String type, Product product) { + return entityManager.createQuery(HQL_GET_BY_PRODUCT_ID_AND_CODE_AVAILABLE) + .setParameter("code", type) + .setParameter("available", true) + .setParameter("pId", product.getId()) + .getResultList(); + } + + @SuppressWarnings("unchecked") + @Override + public List getByTypeAndRelatedProduct(MerchantStore store, String type, Product product) { + return entityManager.createQuery(HQL_GET_BY_CODE_AND_STORE_ID_AND_RP_PRODUCT_ID) + .setParameter("code", type) + .setParameter("available", true) + .setParameter("rpid", product.getId()) + .setParameter("storeId", store.getId()) + .getResultList(); + } +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/review/ProductReviewRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/review/ProductReviewRepository.java new file mode 100755 index 0000000000..6ef483a2ed --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/review/ProductReviewRepository.java @@ -0,0 +1,32 @@ +package com.salesmanager.core.business.repositories.catalog.product.review; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.product.review.ProductReview; + +public interface ProductReviewRepository extends JpaRepository { + + + @Query("select p from ProductReview p join fetch p.customer pc join fetch p.product pp join fetch pp.merchantStore ppm left join fetch p.descriptions pd where p.id = ?1") + ProductReview findOne(Long id); + + @Query("select p from ProductReview p join fetch p.customer pc join fetch p.product pp join fetch pp.merchantStore ppm left join fetch p.descriptions pd where pc.id = ?1") + List findByCustomer(Long customerId); + + @Query("select p from ProductReview p left join fetch p.descriptions pd join fetch p.customer pc join fetch pc.merchantStore pcm left join fetch pc.defaultLanguage pcl left join fetch pc.attributes pca left join fetch pca.customerOption pcao left join fetch pca.customerOptionValue pcav left join fetch pcao.descriptions pcaod left join fetch pcav.descriptions pcavd join fetch p.product pp join fetch pp.merchantStore ppm join fetch p.product pp join fetch pp.merchantStore ppm left join fetch p.descriptions pd where pp.id = ?1") + List findByProduct(Long productId); + + @Query("select p from ProductReview p join fetch p.product pp join fetch pp.merchantStore ppm where pp.id = ?1") + List findByProductNoCustomers(Long productId); + + @Query("select p from ProductReview p left join fetch p.descriptions pd join fetch p.customer pc join fetch pc.merchantStore pcm left join fetch pc.defaultLanguage pcl left join fetch pc.attributes pca left join fetch pca.customerOption pcao left join fetch pca.customerOptionValue pcav left join fetch pcao.descriptions pcaod left join fetch pcav.descriptions pcavd join fetch p.product pp join fetch pp.merchantStore ppm join fetch p.product pp join fetch pp.merchantStore ppm left join fetch p.descriptions pd where pp.id = ?1 and pd.language.id =?2") + List findByProduct(Long productId, Integer languageId); + + @Query("select p from ProductReview p left join fetch p.descriptions pd join fetch p.customer pc join fetch pc.merchantStore pcm left join fetch pc.defaultLanguage pcl left join fetch pc.attributes pca left join fetch pca.customerOption pcao left join fetch pca.customerOptionValue pcav left join fetch pcao.descriptions pcaod left join fetch pcav.descriptions pcavd join fetch p.product pp join fetch pp.merchantStore ppm join fetch p.product pp join fetch pp.merchantStore ppm left join fetch p.descriptions pd where pp.id = ?1 and pc.id = ?2") + ProductReview findByProductAndCustomer(Long productId, Long customerId); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/type/PageableProductTypeRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/type/PageableProductTypeRepository.java new file mode 100644 index 0000000000..3409f73ba7 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/type/PageableProductTypeRepository.java @@ -0,0 +1,17 @@ +package com.salesmanager.core.business.repositories.catalog.product.type; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; + +import com.salesmanager.core.model.catalog.product.type.ProductType; + +public interface PageableProductTypeRepository extends PagingAndSortingRepository { + + + @Query(value = "select distinct p from ProductType p left join fetch p.descriptions pd left join fetch p.merchantStore pm where pm.id=?1", + countQuery = "select count(p) from ProductType p left join p.merchantStore pm where pm.id = ?1") + Page listByStore(Integer storeId, Pageable pageable); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/type/ProductTypeRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/type/ProductTypeRepository.java new file mode 100755 index 0000000000..e54e636874 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/type/ProductTypeRepository.java @@ -0,0 +1,27 @@ +package com.salesmanager.core.business.repositories.catalog.product.type; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.product.type.ProductType; + +public interface ProductTypeRepository extends JpaRepository { + + @Query(value = "select p from ProductType p join fetch p.merchantStore pm where p.code=?1") + ProductType findByCode(String code); + + @Query(value = "select p from ProductType p left join fetch p.descriptions pd left join fetch p.merchantStore pm where p.code=?1 and (pm is null or pm.id=?2)") + ProductType findByCode(String code, Integer store); + + @Query(value = "select p from ProductType p left join fetch p.descriptions pd left join fetch p.merchantStore pm where p.id=?1 and (pm is null or pm.id=?2)") + ProductType findById(Long id, Integer store, int language); + + @Query(value = "select p from ProductType p left join fetch p.descriptions pd left join fetch p.merchantStore pm where p.id=?1 and (pm is null or pm.id=?2)") + ProductType findById(Long id, Integer store); + + @Query(value = "select p from ProductType p left join fetch p.descriptions pd join fetch p.merchantStore pm where p.id in ?1 and (pm is null or pm.id=?2)") + List findByIds(List id, Integer store, int language); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variant/PageableProductVariantGroupRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variant/PageableProductVariantGroupRepository.java new file mode 100644 index 0000000000..76652d8665 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variant/PageableProductVariantGroupRepository.java @@ -0,0 +1,28 @@ +package com.salesmanager.core.business.repositories.catalog.product.variant; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; + +import com.salesmanager.core.model.catalog.product.variant.ProductVariantGroup; + +public interface PageableProductVariantGroupRepository extends PagingAndSortingRepository { + + + + + @Query(value = "select p from ProductVariantGroup p " + + "join fetch p.productVariants pi " + + "join fetch pi.product pip " + + "left join fetch p.images pim " + + "left join fetch pim.descriptions pimd " + + "left join fetch p.merchantStore pm " + + "where pip.id = ?2 and pm.id = ?1", + countQuery = "select p from ProductVariantGroup p " + + "join fetch p.productVariants pi " + + "left join fetch p.merchantStore pm join fetch pi.product pip " + + "where pip.id = ?2 and pm.id = ?1") + Page findByProductId(Integer storeId, Long productId, Pageable pageable); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variant/PageableProductVariantRepositoty.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variant/PageableProductVariantRepositoty.java new file mode 100644 index 0000000000..99eae0a8e5 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variant/PageableProductVariantRepositoty.java @@ -0,0 +1,40 @@ +package com.salesmanager.core.business.repositories.catalog.product.variant; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; + +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; + +public interface PageableProductVariantRepositoty extends PagingAndSortingRepository { + + + + @Query(value = "select p from ProductVariant p " + + "join fetch p.product pr " + + "left join fetch p.variation pv " + + "left join fetch pv.productOption pvpo " + + "left join fetch pv.productOptionValue pvpov " + + "left join fetch pvpo.descriptions pvpod " + + "left join fetch pvpov.descriptions pvpovd " + + + "left join fetch p.variationValue pvv " + + "left join fetch pvv.productOption pvvpo " + + "left join fetch pvv.productOptionValue pvvpov " + + "left join fetch pvvpo.descriptions povvpod " + + "left join fetch pvpov.descriptions pvpovd " + + "left join fetch p.productVariantGroup pig " + + "left join fetch pig.images pigi " + + "left join fetch pigi.descriptions pigid " + + + "left join fetch pr.merchantStore prm " + + "where pr.id = ?2 and prm.id = ?1", + countQuery = "select p from ProductVariant p " + + "join fetch p.product pr " + + "left join fetch pr.merchantStore prm " + + "where pr.id = ?2 and prm.id = ?1") + Page findByProductId(Integer storeId, Long productId, Pageable pageable); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variant/ProductVariantGroupRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variant/ProductVariantGroupRepository.java new file mode 100644 index 0000000000..171e499b91 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variant/ProductVariantGroupRepository.java @@ -0,0 +1,41 @@ +package com.salesmanager.core.business.repositories.catalog.product.variant; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.product.variant.ProductVariantGroup; + +public interface ProductVariantGroupRepository extends JpaRepository { + + + @Query("select distinct p from ProductVariantGroup p" + + " left join fetch p.productVariants pp" + + " left join fetch p.images ppi" + + " left join fetch ppi.descriptions ppid " + + " where p.id = ?1 and p.merchantStore.code = ?2") + Optional findOne(Long id, String storeCode); + + + @Query("select distinct p from ProductVariantGroup p " + + "left join fetch p.productVariants pp " + + "left join fetch p.images ppi " + + "left join fetch ppi.descriptions ppid " + + "join fetch pp.product ppp " + + "join fetch ppp.merchantStore pppm " + + "where pp.id = ?1 and p.merchantStore.code = ?2") + Optional finByProductVariant(Long productVariantId, String storeCode); + + @Query("select distinct p from ProductVariantGroup p " + + "left join fetch p.productVariants pp " + + "left join fetch p.images ppi " + + "left join fetch ppi.descriptions ppid " + + "join fetch pp.product ppp " + + "join fetch ppp.merchantStore pppm " + + "where ppp.id = ?1 and p.merchantStore.code = ?2") + List finByProduct(Long productId, String storeCode); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variant/ProductVariantImageRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variant/ProductVariantImageRepository.java new file mode 100644 index 0000000000..d17e2a13cf --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variant/ProductVariantImageRepository.java @@ -0,0 +1,57 @@ +package com.salesmanager.core.business.repositories.catalog.product.variant; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.product.variant.ProductVariantImage; + +public interface ProductVariantImageRepository extends JpaRepository { + + @Query("select p from ProductVariantImage p" + + " left join fetch p.descriptions pd" + + " join fetch p.productVariantGroup pg" + + " where p.id = ?1") + ProductVariantImage findOne(Long id); + + + @Query("select p from ProductVariantImage p " + + "left join fetch p.descriptions pd " + + "join fetch p.productVariantGroup pg " + + "join fetch pg.productVariants pi " + + "join fetch pi.product ppp " + + "join fetch ppp.merchantStore pppm " + + "where ppp.id = ?1 and pppm.code = ?2") + List finByProduct(Long productId, String storeCode); + + @Query("select p from ProductVariantImage p " + + "left join fetch p.descriptions pd " + + "join fetch p.productVariantGroup pg " + + "join fetch pg.productVariants pi " + + "join fetch pi.product ppp " + + "join fetch ppp.merchantStore pppm " + + "where pg.id = ?1 and pppm.code = ?2") + List finByProductVariantGroup(Long productVariantGroupId, String storeCode); + + /** + @Query("select p from ProductVariantImage p " + + "left join fetch p.descriptions pd " + + "join fetch p.productVariantGroup pg " + + "join fetch pg.productVariants pi " + + "join fetch pi.product ppp " + + "join fetch ppp.merchantStore pppm " + + "where ppp.id = ?1 and pppm.code = ?2 and pd.language.code = ?3") + List finByProduct(Long productId, String storeCode, String lang); + **/ + + @Query("select p from ProductVariantImage p " + + "left join fetch p.descriptions pd " + + "join fetch p.productVariantGroup pg " + + "join fetch pg.productVariants pi " + + "join fetch pi.product ppp " + + "join fetch ppp.merchantStore pppm " + + "where pi.id = ?1 and pppm.code = ?2 and pd.language.code = ?3") + List finByProductVariant(Long productVariantId, String storeCode); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variant/ProductVariantRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variant/ProductVariantRepository.java new file mode 100644 index 0000000000..c81f82cafa --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variant/ProductVariantRepository.java @@ -0,0 +1,128 @@ +package com.salesmanager.core.business.repositories.catalog.product.variant; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; + +public interface ProductVariantRepository extends JpaRepository { + + + + + @Query("select p from ProductVariant p join fetch p.product pr " + + "left join fetch p.variation pv " + + "left join fetch pv.productOption pvpo " + + "left join fetch pv.productOptionValue pvpov " + + "left join fetch pvpo.descriptions pvpod " + + "left join fetch pvpov.descriptions pvpovd " + + + "left join fetch p.variationValue pvv " + + "left join fetch pvv.productOption pvvpo " + + "left join fetch pvv.productOptionValue pvvpov " + + "left join fetch pvvpo.descriptions povvpod " + + "left join fetch pvpov.descriptions povvpovd " + + + "left join fetch pv.merchantStore pvm " + + "where p.id = ?1 and pvm.id = ?2") + Optional findOne(Long id, Integer storeId); + + @Query("select p from ProductVariant p join fetch p.product pr " + + "left join fetch p.variation pv " + + "left join fetch pv.productOption pvpo " + + "left join fetch pv.productOptionValue pvpov " + + "left join fetch pvpo.descriptions pvpod " + + "left join fetch pvpov.descriptions pvpovd " + + + "left join fetch p.variationValue pvv " + + "left join fetch pvv.productOption pvvpo " + + "left join fetch pvv.productOptionValue pvvpov " + + "left join fetch pvvpo.descriptions povvpod " + + "left join fetch pvpov.descriptions povvpovd " + + + "left join fetch pv.merchantStore pvm " + + "where p.id in (?1) and pvm.id = ?2") + List findByIds(List ids, Integer storeId); + + + @Query("select p from ProductVariant p join fetch p.product pr " + + "left join fetch p.variation pv " + + "left join fetch pv.productOption pvpo " + + "left join fetch pv.productOptionValue pvpov " + + "left join fetch pvpo.descriptions pvpod " + + "left join fetch pvpov.descriptions pvpovd " + + + "left join fetch p.variationValue pvv " + + "left join fetch pvv.productOption pvvpo " + + "left join fetch pvv.productOptionValue pvvpov " + + "left join fetch pvvpo.descriptions povvpod " + + "left join fetch pvpov.descriptions povvpovd " + + + "left join fetch pr.merchantStore prm " + + "where p.id = ?1 and pr.id = ?2 and prm.id = ?3") + Optional findById(Long id, Long productId, Integer storeId); + + + + @Query("select p from ProductVariant p join fetch p.product pr " + + "left join fetch p.variation pv " + + "left join fetch pv.productOption pvpo " + + "left join fetch pv.productOptionValue pvpov " + + "left join fetch pvpo.descriptions pvpod " + + "left join fetch pvpov.descriptions pvpovd " + + + "left join fetch p.variationValue pvv " + + "left join fetch pvv.productOption pvvpo " + + "left join fetch pvv.productOptionValue pvvpov " + + "left join fetch pvvpo.descriptions povvpod " + + "left join fetch pvpov.descriptions povvpovd " + + + "left join fetch pr.merchantStore prm " + + "where pvpod.language.id = ?4 " + + "and pvpovd.language.id = ?4 " + + "and povvpod.language.id = ?4 " + + "and povvpovd.language.id = ?4 " + + "and pr.id = ?2 and p.code = ?1 and prm.id = ?3") + Optional findBySku(String code, Long productId, Integer storeId, Integer languageId); + + + /** + * Gets the whole graph + * @param storeId + * @param productId + * @return + */ + @Query(value = "select distinct p from ProductVariant as p " + + "join fetch p.product pr " + + "left join fetch p.variation pv " + + "left join fetch pv.productOption pvpo " + + "left join fetch pv.productOptionValue pvpov " + + "left join fetch pvpo.descriptions pvpod " + + "left join fetch pvpov.descriptions pvpovd " + + + "left join fetch p.variationValue pvv " + + "left join fetch pvv.productOption pvvpo " + + "left join fetch pvv.productOptionValue pvvpov " + + "left join fetch pvvpo.descriptions povvpod " + + "left join fetch pvpov.descriptions pvpovd " + + "left join fetch p.productVariantGroup pig " + + "left join fetch pig.images pigi " + + "left join fetch pigi.descriptions pigid " + + + + "left join fetch pv.merchantStore pvm " + + "where pr.id = ?2 and pvm.id = ?1") + List findByProductId(Integer storeId, Long productId); + + + + @Query("select p from ProductVariant p join fetch p.product pr where p.sku = ?1 and pr.id = ?2") + ProductVariant existsBySkuAndProduct(String sku, Long productId); + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variation/PageableProductVariationRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variation/PageableProductVariationRepository.java new file mode 100644 index 0000000000..f45b224a6f --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variation/PageableProductVariationRepository.java @@ -0,0 +1,21 @@ +package com.salesmanager.core.business.repositories.catalog.product.variation; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; + +import com.salesmanager.core.model.catalog.product.variation.ProductVariation; + +public interface PageableProductVariationRepository extends PagingAndSortingRepository { + + + @Query(value = "select distinct p from ProductVariation p join fetch p.merchantStore pm " + + "left join fetch p.productOption po left join fetch po.descriptions " + + "left join fetch p.productOptionValue pp left join fetch pp.descriptions " + + "where pm.id = ?1 and (?2 is null or p.code like %?2%)", + countQuery = "select count(p) from ProductVariation p join p.merchantStore pm where pm.id = ?1 and (?2 is null or p.code like %?2%)") + Page list(int merchantStoreId, String code, Pageable pageable); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variation/ProductVariationRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variation/ProductVariationRepository.java new file mode 100644 index 0000000000..8c8fa3feb5 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/catalog/product/variation/ProductVariationRepository.java @@ -0,0 +1,40 @@ +package com.salesmanager.core.business.repositories.catalog.product.variation; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.catalog.product.variation.ProductVariation; + +public interface ProductVariationRepository extends JpaRepository { + + @Query("select distinct p from ProductVariation p " + + "join fetch p.merchantStore pm " + + "left join fetch p.productOption po " + + "left join fetch po.descriptions pod " + + "left join fetch p.productOptionValue pv " + + "left join fetch pv.descriptions pvd where pm.id = ?1 and p.id = ?2 and pod.language.id = ?3") + Optional findOne(Integer storeId, Long id, Integer language); + + @Query("select distinct p from ProductVariation p " + + "join fetch p.merchantStore pm " + + "left join fetch p.productOption po " + + "left join fetch po.descriptions pod " + + "left join fetch p.productOptionValue pv " + + "left join fetch pv.descriptions pvd where pm.id = ?1 and p.id = ?2") + Optional findOne(Integer storeId, Long id); + + @Query("select distinct p from ProductVariation p join fetch p.merchantStore pm left join fetch p.productOption po left join fetch po.descriptions pod left join fetch p.productOptionValue pv left join fetch pv.descriptions pvd where p.code = ?1 and pm.id = ?2") + Optional findByCode(String code, Integer storeId); + + @Query("select distinct p from ProductVariation p " + + "join fetch p.merchantStore pm " + + "left join fetch p.productOption po " + + "left join fetch po.descriptions pod " + + "left join fetch p.productOptionValue pv " + + "left join fetch pv.descriptions pvd where pm.id = ?1 and p.id in (?2)") + List findByIds(Integer storeId, List ids); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/content/ContentRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/content/ContentRepository.java new file mode 100755 index 0000000000..14d3e8f271 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/content/ContentRepository.java @@ -0,0 +1,45 @@ +package com.salesmanager.core.business.repositories.content; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.content.Content; +import com.salesmanager.core.model.content.ContentType; + +public interface ContentRepository extends JpaRepository, ContentRepositoryCustom { + + + @Query("select c from Content c left join fetch c.descriptions cd join fetch c.merchantStore cm where c.contentType = ?1 and cm.id = ?2 and cd.language.id = ?3 order by c.sortOrder asc") + List findByType(ContentType contentType, Integer storeId, Integer languageId); + + @Query("select c from Content c left join fetch c.descriptions cd join fetch c.merchantStore cm where c.contentType = ?1 and cm.id = ?2 order by c.sortOrder asc") + List findByType(ContentType contentType, Integer storeId); + + @Query("select c from Content c join fetch c.merchantStore cm where c.code = ?1 and c.contentType = ?2 and cm.id = ?3") + Content findByCodeAndType(String code, ContentType contentType, Integer storeId); + + @Query("select c from Content c left join fetch c.descriptions cd join fetch c.merchantStore cm where c.contentType in (?1) and cm.id = ?2 and cd.language.id = ?3 order by c.sortOrder asc") + List findByTypes(List contentTypes, Integer storeId, Integer languageId); + + @Query("select c from Content c left join fetch c.descriptions cd join fetch c.merchantStore cm where c.contentType in (?1) and cm.id = ?2 order by c.sortOrder asc") + List findByTypes(List contentTypes, Integer storeId); + + @Query("select c from Content c left join fetch c.descriptions cd join fetch c.merchantStore cm where c.code = ?1 and cm.id = ?2") + Content findByCode(String code, Integer storeId); + + @Query("select c from Content c left join fetch c.descriptions cd join fetch c.merchantStore cm where c.contentType = ?1 and cm.id=?3 and c.code like ?2 and cd.language.id = ?4") + List findByCodeLike(ContentType contentType, String code, Integer storeId, Integer languageId); + + @Query("select c from Content c left join fetch c.descriptions cd join fetch c.merchantStore cm where c.code = ?1 and cm.id = ?2 and cd.language.id = ?3") + Content findByCode(String code, Integer storeId, Integer languageId); + + @Query("select c from Content c left join fetch c.descriptions cd join fetch c.merchantStore cm where c.id = ?1 and cd.language.id = ?2") + Content findByIdAndLanguage(Long contentId, Integer languageId); + + @Query("select c from Content c left join fetch c.descriptions cd join fetch c.merchantStore cm where c.id = ?1") + Content findOne(Long contentId); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/content/ContentRepositoryCustom.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/content/ContentRepositoryCustom.java new file mode 100755 index 0000000000..4a4a41e7ef --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/content/ContentRepositoryCustom.java @@ -0,0 +1,19 @@ +package com.salesmanager.core.business.repositories.content; + +import java.util.List; + +import com.salesmanager.core.model.content.ContentDescription; +import com.salesmanager.core.model.content.ContentType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + + +public interface ContentRepositoryCustom { + + List listNameByType(List contentType, + MerchantStore store, Language language); + + ContentDescription getBySeUrl(MerchantStore store, String seUrl); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/content/ContentRepositoryImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/content/ContentRepositoryImpl.java new file mode 100755 index 0000000000..5fab2555ba --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/content/ContentRepositoryImpl.java @@ -0,0 +1,109 @@ +package com.salesmanager.core.business.repositories.content; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; + +import com.salesmanager.core.model.content.Content; +import com.salesmanager.core.model.content.ContentDescription; +import com.salesmanager.core.model.content.ContentType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + + +public class ContentRepositoryImpl implements ContentRepositoryCustom { + + + @PersistenceContext + private EntityManager em; + + @Override + public List listNameByType(List contentType, MerchantStore store, Language language) { + + + + StringBuilder qs = new StringBuilder(); + + qs.append("select c from Content c "); + qs.append("left join fetch c.descriptions cd join fetch c.merchantStore cm "); + qs.append("where c.contentType in (:ct) "); + qs.append("and cm.id =:cm "); + qs.append("and cd.language.id =:cl "); + qs.append("and c.visible=true "); + qs.append("order by c.sortOrder"); + + String hql = qs.toString(); + Query q = this.em.createQuery(hql); + + q.setParameter("ct", contentType); + q.setParameter("cm", store.getId()); + q.setParameter("cl", language.getId()); + + + @SuppressWarnings("unchecked") + List contents = q.getResultList(); + + List descriptions = new ArrayList(); + for(Content c : contents) { + String name = c.getDescription().getName(); + String url = c.getDescription().getSeUrl(); + ContentDescription contentDescription = new ContentDescription(); + contentDescription.setName(name); + contentDescription.setSeUrl(url); + contentDescription.setContent(c); + descriptions.add(contentDescription); + + } + + return descriptions; + + } + + @Override + public ContentDescription getBySeUrl(MerchantStore store,String seUrl) { + + StringBuilder qs = new StringBuilder(); + + qs.append("select c from Content c "); + qs.append("left join fetch c.descriptions cd join fetch c.merchantStore cm "); + qs.append("where cm.id =:cm "); + qs.append("and c.visible =true "); + qs.append("and cd.seUrl =:se "); + + + String hql = qs.toString(); + Query q = this.em.createQuery(hql); + + q.setParameter("cm", store.getId()); + q.setParameter("se", seUrl); + + + Content content = (Content)q.getSingleResult(); + + + if(content!=null) { + return content.getDescription(); + } + + @SuppressWarnings("unchecked") + List results = q.getResultList(); + if (results.isEmpty()) { + return null; + } else if (results.size() >= 1) { + content = results.get(0); + } + + if(content!=null) { + return content.getDescription(); + } + + + return null; + + } + + +} \ No newline at end of file diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/content/PageContentRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/content/PageContentRepository.java new file mode 100644 index 0000000000..ef41b23985 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/content/PageContentRepository.java @@ -0,0 +1,26 @@ +package com.salesmanager.core.business.repositories.content; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; + +import com.salesmanager.core.model.content.Content; +import com.salesmanager.core.model.content.ContentType; +import com.salesmanager.core.model.merchant.MerchantStore; + +public interface PageContentRepository extends PagingAndSortingRepository { + + + + @Query(value = "select c from Content c left join fetch c.descriptions cd join fetch c.merchantStore cm where c.contentType = ?1 and cm.id = ?2 order by c.sortOrder asc", + countQuery = "select count(distinct c) from Content c join c.merchantStore cm where c.contentType = ?1 and cm.id = ?2") + Page findByContentType(ContentType contentType, Integer storeId, Pageable pageable); + + @Query(value = "select c from Content c left join fetch c.descriptions cd join fetch c.merchantStore cm join fetch cd.language cdl where c.contentType = ?1 and cm.id = ?2 and cdl.id = ?3 order by c.sortOrder asc", + countQuery = "select count(distinct c) from Content c join c.merchantStore cm where c.contentType = ?1 and cm.id = ?2") + Page findByContentType(ContentType contentTypes, Integer storeId, Integer language, Pageable pageable); + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/CustomerRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/CustomerRepository.java new file mode 100755 index 0000000000..25bcc36120 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/CustomerRepository.java @@ -0,0 +1,80 @@ +package com.salesmanager.core.business.repositories.customer; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.customer.Customer; + +public interface CustomerRepository extends JpaRepository, CustomerRepositoryCustom { + + + @Query("select c from Customer c join fetch c.merchantStore cm left join fetch c.defaultLanguage cl left join fetch c.attributes ca left join fetch ca.customerOption cao left join fetch ca.customerOptionValue cav left join fetch cao.descriptions caod left join fetch cav.descriptions left join fetch c.groups where c.id = ?1") + Customer findOne(Long id); + + @Query("select distinct c from Customer c join fetch c.merchantStore cm left join fetch c.defaultLanguage cl left join fetch c.attributes ca left join fetch ca.customerOption cao left join fetch ca.customerOptionValue cav left join fetch cao.descriptions caod left join fetch cav.descriptions left join fetch c.groups where c.billing.firstName = ?1") + List findByName(String name); + + @Query("select c from Customer c join fetch c.merchantStore cm left join fetch c.defaultLanguage cl left join fetch c.attributes ca left join fetch ca.customerOption cao left join fetch ca.customerOptionValue cav left join fetch cao.descriptions caod left join fetch cav.descriptions left join fetch c.groups where c.nick = ?1") + Customer findByNick(String nick); + + @Query("select c from Customer c " + + "join fetch c.merchantStore cm " + + "left join fetch c.defaultLanguage cl " + + "left join fetch c.attributes ca " + + "left join fetch ca.customerOption cao " + + "left join fetch ca.customerOptionValue cav " + + "left join fetch cao.descriptions caod " + + "left join fetch cav.descriptions " + + "left join fetch c.groups " + + "left join fetch c.delivery cd " + + "left join fetch c.billing cb " + + "left join fetch cd.country " + + "left join fetch cd.zone " + + "left join fetch cb.country " + + "left join fetch cb.zone " + + "where c.nick = ?1 and cm.id = ?2") + Customer findByNick(String nick, int storeId); + + @Query("select c from Customer c " + + "join fetch c.merchantStore cm " + + "left join fetch c.defaultLanguage cl " + + "left join fetch c.attributes ca " + + "left join fetch ca.customerOption cao " + + "left join fetch ca.customerOptionValue cav " + + "left join fetch cao.descriptions caod " + + "left join fetch cav.descriptions " + + "left join fetch c.groups " + + "left join fetch c.delivery cd " + + "left join fetch c.billing cb " + + "left join fetch cd.country " + + "left join fetch cd.zone " + + "left join fetch cb.country " + + "left join fetch cb.zone " + + "where c.nick = ?1 and cm.code = ?2") + Customer findByNick(String nick, String store); + + @Query("select c from Customer c " + + "join fetch c.merchantStore cm " + + "left join fetch c.defaultLanguage cl " + + "left join fetch c.attributes ca " + + "left join fetch ca.customerOption cao " + + "left join fetch ca.customerOptionValue cav " + + "left join fetch cao.descriptions caod " + + "left join fetch cav.descriptions " + + "left join fetch c.groups " + + "left join fetch c.delivery cd " + + "left join fetch c.billing cb " + + "left join fetch cd.country " + + "left join fetch cd.zone " + + "left join fetch cb.country " + + "left join fetch cb.zone " + + "where c.credentialsResetRequest.credentialsRequest = ?1 and cm.code = ?2") + Customer findByResetPasswordToken(String token, String store); + + @Query("select distinct c from Customer c join fetch c.merchantStore cm left join fetch c.defaultLanguage cl left join fetch c.attributes ca left join fetch ca.customerOption cao left join fetch ca.customerOptionValue cav left join fetch cao.descriptions caod left join fetch cav.descriptions left join fetch c.groups where cm.id = ?1") + List findByStore(int storeId); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/CustomerRepositoryCustom.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/CustomerRepositoryCustom.java new file mode 100755 index 0000000000..a403751d9b --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/CustomerRepositoryCustom.java @@ -0,0 +1,14 @@ +package com.salesmanager.core.business.repositories.customer; + +import com.salesmanager.core.model.customer.CustomerCriteria; +import com.salesmanager.core.model.customer.CustomerList; +import com.salesmanager.core.model.merchant.MerchantStore; + + + +public interface CustomerRepositoryCustom { + + CustomerList listByStore(MerchantStore store, CustomerCriteria criteria); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/CustomerRepositoryImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/CustomerRepositoryImpl.java new file mode 100755 index 0000000000..0ea05ca094 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/CustomerRepositoryImpl.java @@ -0,0 +1,147 @@ +package com.salesmanager.core.business.repositories.customer; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; + +import org.apache.commons.lang3.StringUtils; + +import com.salesmanager.core.model.customer.CustomerCriteria; +import com.salesmanager.core.model.customer.CustomerList; +import com.salesmanager.core.model.merchant.MerchantStore; + + +public class CustomerRepositoryImpl implements CustomerRepositoryCustom { + + + @PersistenceContext + private EntityManager em; + + @SuppressWarnings("unchecked") + @Override + public CustomerList listByStore(MerchantStore store, CustomerCriteria criteria) { + + + CustomerList customerList = new CustomerList(); + StringBuilder countBuilderSelect = new StringBuilder(); + StringBuilder objectBuilderSelect = new StringBuilder(); + + String baseCountQuery = "select count(c) from Customer as c"; + String baseQuery = "select c from Customer as c left join fetch c.delivery.country left join fetch c.delivery.zone left join fetch c.billing.country left join fetch c.billing.zone"; + countBuilderSelect.append(baseCountQuery); + objectBuilderSelect.append(baseQuery); + + StringBuilder countBuilderWhere = new StringBuilder(); + StringBuilder objectBuilderWhere = new StringBuilder(); + String whereQuery = " where c.merchantStore.id=:mId"; + countBuilderWhere.append(whereQuery); + objectBuilderWhere.append(whereQuery); + + if(!StringUtils.isBlank(criteria.getName())) { + String nameQuery =" and c.billing.firstName like:nm or c.billing.lastName like:nm"; + countBuilderWhere.append(nameQuery); + objectBuilderWhere.append(nameQuery); + } + + if(!StringUtils.isBlank(criteria.getFirstName())) { + String nameQuery =" and c..billing.firstName like:fn"; + countBuilderWhere.append(nameQuery); + objectBuilderWhere.append(nameQuery); + } + + if(!StringUtils.isBlank(criteria.getLastName())) { + String nameQuery =" and c.billing.lastName like:ln"; + countBuilderWhere.append(nameQuery); + objectBuilderWhere.append(nameQuery); + } + + if(!StringUtils.isBlank(criteria.getEmail())) { + String mailQuery =" and c.emailAddress like:email"; + countBuilderWhere.append(mailQuery); + objectBuilderWhere.append(mailQuery); + } + + if(!StringUtils.isBlank(criteria.getCountry())) { + String countryQuery =" and c.billing.country.isoCode like:country"; + countBuilderWhere.append(countryQuery); + objectBuilderWhere.append(countryQuery); + } + + objectBuilderSelect.append(" left join fetch c.attributes ca left join fetch ca.customerOption cao left join fetch ca.customerOptionValue cav left join fetch cao.descriptions caod left join fetch cav.descriptions left join fetch c.groups"); + + //count query + Query countQ = em.createQuery( + countBuilderSelect.toString() + countBuilderWhere.toString()); + + //object query + Query objectQ = em.createQuery( + objectBuilderSelect.toString() + objectBuilderWhere.toString()); + + countQ.setParameter("mId", store.getId()); + objectQ.setParameter("mId", store.getId()); + + + if(!StringUtils.isBlank(criteria.getName())) { + String nameParam = new StringBuilder().append("%").append(criteria.getName()).append("%").toString(); + countQ.setParameter("nm",nameParam); + objectQ.setParameter("nm",nameParam); + } + + if(!StringUtils.isBlank(criteria.getFirstName())) { + String nameParam = new StringBuilder().append("%").append(criteria.getFirstName()).append("%").toString(); + countQ.setParameter("fn",nameParam); + objectQ.setParameter("fn",nameParam); + } + + if(!StringUtils.isBlank(criteria.getLastName())) { + String nameParam = new StringBuilder().append("%").append(criteria.getLastName()).append("%").toString(); + countQ.setParameter("ln",nameParam); + objectQ.setParameter("ln",nameParam); + } + + if(!StringUtils.isBlank(criteria.getEmail())) { + String email = new StringBuilder().append("%").append(criteria.getEmail()).append("%").toString(); + countQ.setParameter("email",email); + objectQ.setParameter("email",email); + } + + if(!StringUtils.isBlank(criteria.getCountry())) { + String country = new StringBuilder().append("%").append(criteria.getCountry()).append("%").toString(); + countQ.setParameter("country",country); + objectQ.setParameter("country",country); + } + + + + + Number count = (Number) countQ.getSingleResult(); + + customerList.setTotalCount(count.intValue()); + + if(count.intValue()==0) + return customerList; + + //TO BE USED + int max = criteria.getMaxCount(); + int first = criteria.getStartIndex(); + + objectQ.setFirstResult(first); + + + + if(max>0) { + int maxCount = first + max; + + objectQ.setMaxResults(Math.min(maxCount, count.intValue())); + } + + customerList.setCustomers(objectQ.getResultList()); + + return customerList; + + + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/attribute/CustomerAttributeRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/attribute/CustomerAttributeRepository.java new file mode 100755 index 0000000000..4a1942e7e9 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/attribute/CustomerAttributeRepository.java @@ -0,0 +1,27 @@ +package com.salesmanager.core.business.repositories.customer.attribute; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.customer.attribute.CustomerAttribute; + +public interface CustomerAttributeRepository extends JpaRepository { + + + @Query("select a from CustomerAttribute a left join fetch a.customerOption aco left join fetch a.customerOptionValue acov left join fetch aco.descriptions acod left join fetch acov.descriptions acovd where a.id = ?1") + CustomerAttribute findOne(Long id); + + @Query("select a from CustomerAttribute a join fetch a.customer ac left join fetch a.customerOption aco join fetch aco.merchantStore acom left join fetch a.customerOptionValue acov left join fetch aco.descriptions acod left join fetch acov.descriptions acovd where acom.id = ?1 and ac.id = ?2 and aco.id = ?3") + CustomerAttribute findByOptionId(Integer merchantId,Long customerId,Long id); + + @Query("select a from CustomerAttribute a join fetch a.customer ac left join fetch a.customerOption aco join fetch aco.merchantStore acom left join fetch a.customerOptionValue acov left join fetch aco.descriptions acod left join fetch acov.descriptions acovd where acom.id = ?1 and aco.id = ?2") + List findByOptionId(Integer merchantId,Long id); + + @Query("select distinct a from CustomerAttribute a join fetch a.customer ac left join fetch a.customerOption aco join fetch aco.merchantStore acom left join fetch a.customerOptionValue acov left join fetch aco.descriptions acod left join fetch acov.descriptions acovd where acom.id = ?1 and ac.id = ?2") + List findByCustomerId(Integer merchantId,Long customerId); + + @Query("select a from CustomerAttribute a join fetch a.customer ac left join fetch a.customerOption aco join fetch aco.merchantStore acom left join fetch a.customerOptionValue acov left join fetch aco.descriptions acod left join fetch acov.descriptions acovd where acom.id = ?1 and acov.id = ?2") + List findByOptionValueId(Integer merchantId,Long Id); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/attribute/CustomerOptionRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/attribute/CustomerOptionRepository.java new file mode 100755 index 0000000000..dd26a915c7 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/attribute/CustomerOptionRepository.java @@ -0,0 +1,22 @@ +package com.salesmanager.core.business.repositories.customer.attribute; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.customer.attribute.CustomerOption; + +public interface CustomerOptionRepository extends JpaRepository { + + + @Query("select o from CustomerOption o join fetch o.merchantStore om left join fetch o.descriptions od where o.id = ?1") + CustomerOption findOne(Long id); + + @Query("select o from CustomerOption o join fetch o.merchantStore om left join fetch o.descriptions od where om.id = ?1 and o.code = ?2") + CustomerOption findByCode(Integer merchantId, String code); + + @Query("select o from CustomerOption o join fetch o.merchantStore om left join fetch o.descriptions od where om.id = ?1 and od.language.id = ?2") + List findByStore(Integer merchantId, Integer languageId); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/attribute/CustomerOptionSetRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/attribute/CustomerOptionSetRepository.java new file mode 100755 index 0000000000..bcabb96b39 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/attribute/CustomerOptionSetRepository.java @@ -0,0 +1,25 @@ +package com.salesmanager.core.business.repositories.customer.attribute; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.customer.attribute.CustomerOptionSet; + +public interface CustomerOptionSetRepository extends JpaRepository { + + + @Query("select c from CustomerOptionSet c join fetch c.customerOption co join fetch c.customerOptionValue cov join fetch co.merchantStore com left join fetch co.descriptions cod left join fetch cov.descriptions covd where c.id = ?1") + CustomerOptionSet findOne(Long id); + + @Query("select c from CustomerOptionSet c join fetch c.customerOption co join fetch c.customerOptionValue cov join fetch co.merchantStore com left join fetch co.descriptions cod left join fetch cov.descriptions covd where com.id = ?1 and co.id = ?2") + List findByOptionId(Integer merchantStoreId, Long id); + + @Query("select c from CustomerOptionSet c join fetch c.customerOption co join fetch c.customerOptionValue cov join fetch co.merchantStore com left join fetch co.descriptions cod left join fetch cov.descriptions covd where com.id = ?1 and cov.id = ?2") + List findByOptionValueId(Integer merchantStoreId, Long id); + + @Query("select c from CustomerOptionSet c join fetch c.customerOption co join fetch c.customerOptionValue cov join fetch co.merchantStore com left join fetch co.descriptions cod left join fetch cov.descriptions covd where com.id = ?1 and cod.language.id = ?2 and covd.language.id = ?2 order by c.sortOrder asc") + List findByStore(Integer merchantStoreId, Integer languageId); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/attribute/CustomerOptionValueRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/attribute/CustomerOptionValueRepository.java new file mode 100755 index 0000000000..086be772b3 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/attribute/CustomerOptionValueRepository.java @@ -0,0 +1,21 @@ +package com.salesmanager.core.business.repositories.customer.attribute; + +import com.salesmanager.core.model.customer.attribute.CustomerOptionValue; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface CustomerOptionValueRepository extends JpaRepository { + + + @Query("select o from CustomerOptionValue o join fetch o.merchantStore om left join fetch o.descriptions od where o.id = ?1") + CustomerOptionValue findOne(Long id); + + @Query("select o from CustomerOptionValue o join fetch o.merchantStore om left join fetch o.descriptions od where om.id = ?1 and o.code = ?2") + CustomerOptionValue findByCode(Integer merchantId, String code); + + @Query("select o from CustomerOptionValue o join fetch o.merchantStore om left join fetch o.descriptions od where om.id = ?1 and od.language.id = ?2") + List findByStore(Integer merchantId, Integer languageId); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/optin/CustomerOptinRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/optin/CustomerOptinRepository.java new file mode 100755 index 0000000000..ec93f4173b --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/optin/CustomerOptinRepository.java @@ -0,0 +1,17 @@ +package com.salesmanager.core.business.repositories.customer.optin; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.system.optin.CustomerOptin; + +public interface CustomerOptinRepository extends JpaRepository { + + @Query("select distinct c from CustomerOptin as c left join fetch c.optin o join fetch o.merchant om where om.id = ?1 and o.code = ?2") + List findByCode(Integer storeId, String code); + + @Query("select distinct c from CustomerOptin as c left join fetch c.optin o join fetch o.merchant om where om.id = ?1 and o.code = ?2 and c.email = ?3") + CustomerOptin findByMerchantAndCodeAndEmail(Integer storeId, String code, String email); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/review/CustomerReviewRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/review/CustomerReviewRepository.java new file mode 100755 index 0000000000..2da3017410 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/customer/review/CustomerReviewRepository.java @@ -0,0 +1,36 @@ +package com.salesmanager.core.business.repositories.customer.review; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.customer.review.CustomerReview; + +public interface CustomerReviewRepository extends JpaRepository { + + String customerQuery = "" + + "select distinct r from CustomerReview r join fetch " + + "r.customer rc " + //+ "join fetch rc.attributes rca left join " + //+ "fetch rca.customerOption rcao left join fetch rca.customerOptionValue " + //+ "rcav left join fetch rcao.descriptions rcaod left join fetch rcav.descriptions " + + "join fetch r.reviewedCustomer rr join fetch rc.merchantStore rrm " + + "left join fetch r.descriptions rd "; + + + @Query("select r from CustomerReview r join fetch r.customer rc join fetch r.reviewedCustomer rr join fetch rc.merchantStore rrm left join fetch r.descriptions rd where r.id = ?1") + CustomerReview findOne(Long id); + + @Query("select distinct r from CustomerReview r join fetch r.customer rc join fetch r.reviewedCustomer rr join fetch rc.merchantStore rrm left join fetch r.descriptions rd where rc.id = ?1") + List findByReviewer(Long id); + + @Query("select distinct r from CustomerReview r join fetch r.customer rc join fetch r.reviewedCustomer rr join fetch rc.merchantStore rrm left join fetch r.descriptions rd where rr.id = ?1") + List findByReviewed(Long id); + + @Query( customerQuery + "where rc.id = ?1 and rr.id = ?2") + CustomerReview findByRevieweAndReviewed(Long reviewer, Long reviewed); + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/merchant/MerchantRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/merchant/MerchantRepository.java new file mode 100755 index 0000000000..b76ddf0a41 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/merchant/MerchantRepository.java @@ -0,0 +1,51 @@ +package com.salesmanager.core.business.repositories.merchant; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.merchant.MerchantStore; + +public interface MerchantRepository extends JpaRepository, MerchantRepositoryCustom { + + + @Query("select m from MerchantStore m " + + "left join fetch m.parent mp" + + "left join fetch m.country mc " + + "left join fetch m.currency mc " + + "left join fetch m.zone mz " + + "left join fetch m.defaultLanguage md " + + "left join fetch m.languages mls where m.code = ?1") + MerchantStore findByCode(String code); + + @Query("select m from MerchantStore m left join fetch m.parent mp left join fetch m.country mc left join fetch m.currency mc left join fetch m.zone mz left join fetch m.defaultLanguage md left join fetch m.languages mls where m.id = ?1") + MerchantStore getById(int id); + + + @Query("select distinct m from MerchantStore m left join fetch m.parent mp left join fetch m.country mc left join fetch m.currency mc left join fetch m.zone mz left join fetch m.defaultLanguage md left join fetch m.languages mls where mp.code = ?1") + List getByParent(String code); + + @Query("SELECT COUNT(m) > 0 FROM MerchantStore m WHERE m.code = :code") + boolean existsByCode(String code); + + @Query("select new com.salesmanager.core.model.merchant.MerchantStore(m.id, m.code, m.storename) from MerchantStore m") + List findAllStoreNames(); + + @Query(value = "select new com.salesmanager.core.model.merchant.MerchantStore(m.id, m.code, m.storename) from MerchantStore m left join m.parent mp " + + "where mp.code = ?1 or m.code = ?1") + List findAllStoreNames(String storeCode); + + @Query(value = "select new com.salesmanager.core.model.merchant.MerchantStore(m.id, m.code, m.storename) from MerchantStore m left join m.parent mp " + + "where mp.code in ?1 or m.code in ?1") + List findAllStoreNames(List storeCode); + + @Query("select new com.salesmanager.core.model.merchant.MerchantStore(m.id, m.code, m.storename, m.storeEmailAddress) from MerchantStore m") + List findAllStoreCodeNameEmail(); + + @Query( + value = "select * from {h-schema}MERCHANT_STORE m " + + "where m.STORE_CODE = ?1 or ?2 is null or m.PARENT_ID = ?2", + nativeQuery = true) + List listByGroup(String storeCode, Integer id); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/merchant/MerchantRepositoryCustom.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/merchant/MerchantRepositoryCustom.java new file mode 100755 index 0000000000..52b53b9bc1 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/merchant/MerchantRepositoryCustom.java @@ -0,0 +1,14 @@ +package com.salesmanager.core.business.repositories.merchant; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.common.GenericEntityList; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.merchant.MerchantStoreCriteria; + +public interface MerchantRepositoryCustom { + + GenericEntityList listByCriteria(MerchantStoreCriteria criteria) + throws ServiceException; + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/merchant/MerchantRepositoryImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/merchant/MerchantRepositoryImpl.java new file mode 100755 index 0000000000..93e6a3efe8 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/merchant/MerchantRepositoryImpl.java @@ -0,0 +1,96 @@ +package com.salesmanager.core.business.repositories.merchant; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.utils.RepositoryHelper; +import com.salesmanager.core.model.common.GenericEntityList; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.merchant.MerchantStoreCriteria; + +public class MerchantRepositoryImpl implements MerchantRepositoryCustom { + + @PersistenceContext + private EntityManager em; + + private static final Logger LOGGER = LoggerFactory.getLogger(MerchantRepositoryImpl.class); + + + @SuppressWarnings({"rawtypes", "unchecked"}) + @Override + public GenericEntityList listByCriteria(MerchantStoreCriteria criteria) throws ServiceException { + try { + StringBuilder req = new StringBuilder(); + req.append( + "select distinct m from MerchantStore m left join fetch m.country mc left join fetch m.parent cp left join fetch m.currency mc left join fetch m.zone mz left join fetch m.defaultLanguage md left join fetch m.languages mls"); + StringBuilder countBuilder = new StringBuilder(); + countBuilder.append("select count(distinct m) from MerchantStore m"); + if (criteria.getCode() != null) { + req.append(" where lower(m.code) like:code"); + countBuilder.append(" where lower(m.code) like:code"); + } + if (criteria.getName() != null) { + if (criteria.getCode() == null) { + req.append(" where"); + countBuilder.append(" where "); + } else { + req.append(" or"); + countBuilder.append(" or "); + } + req.append(" lower(m.storename) like:name"); + countBuilder.append(" lower(m.storename) like:name"); + } + + if (!StringUtils.isBlank(criteria.getCriteriaOrderByField())) { + req.append(" order by m.").append(criteria.getCriteriaOrderByField()).append(" ") + .append(criteria.getOrderBy().name().toLowerCase()); + } + + Query countQ = this.em.createQuery(countBuilder.toString()); + + String hql = req.toString(); + Query q = this.em.createQuery(hql); + + if (criteria.getCode() != null) { + countQ.setParameter("code", "%" + criteria.getCode().toLowerCase() + "%"); + q.setParameter("code", "%" + criteria.getCode().toLowerCase() + "%"); + } + if (criteria.getName() != null) { + countQ.setParameter("name", "%" + criteria.getCode().toLowerCase() + "%"); + q.setParameter("name", "%" + criteria.getCode().toLowerCase() + "%"); + } + + + Number count = (Number) countQ.getSingleResult(); + + GenericEntityList entityList = new GenericEntityList(); + entityList.setTotalCount(count.intValue()); + + q = RepositoryHelper.paginateQuery(q, count, entityList, criteria); + + + List stores = q.getResultList(); + entityList.setList(stores); + + + return entityList; + + + + } catch (javax.persistence.NoResultException ers) { + } catch (Exception e) { + LOGGER.error(e.getMessage()); + throw new ServiceException(e); + } + return null; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/merchant/PageableMerchantRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/merchant/PageableMerchantRepository.java new file mode 100644 index 0000000000..9c9102829f --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/merchant/PageableMerchantRepository.java @@ -0,0 +1,39 @@ +package com.salesmanager.core.business.repositories.merchant; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; + +import com.salesmanager.core.model.merchant.MerchantStore; + +public interface PageableMerchantRepository extends PagingAndSortingRepository { + + /* + * List by parent store + */ + @Query(value = "select distinct m from MerchantStore m left join fetch m.parent mp left join fetch m.country mc left join fetch m.currency mc left join fetch m.zone mz left join fetch m.defaultLanguage md left join fetch m.languages mls where mp.code = ?1", countQuery = "select count(distinct m) from MerchantStore m join m.parent mp where mp.code = ?1") + Page listByStore(String code, Pageable pageable); + + @Query(value = "select distinct m from MerchantStore m left join fetch m.parent mp left join fetch m.country mc left join fetch m.currency mc left join fetch m.zone mz left join fetch m.defaultLanguage md left join fetch m.languages mls where (?1 is null or m.storename like %?1%)", countQuery = "select count(distinct m) from MerchantStore m where (?1 is null or m.storename like %?1%)") + Page listAll(String storeName, Pageable pageable); + + @Query(value = "select distinct m from MerchantStore m left join fetch m.parent mp " + + "left join fetch m.country mc " + "left join fetch m.currency mc left " + "join fetch m.zone mz " + + "left join fetch m.defaultLanguage md " + "left join fetch m.languages mls " + + "where m.retailer = true and (?1 is null or m.storename like %?1%)", countQuery = "select count(distinct m) from MerchantStore m join m.parent " + + "where m.retailer = true and (?1 is null or m.storename like %?1%)") + Page listAllRetailers(String storeName, Pageable pageable); + + @Query(value = "select distinct m from MerchantStore m left join m.parent mp " + "left join fetch m.country pc " + + "left join fetch m.currency pcu " + "left join fetch m.languages pl " + "left join fetch m.zone pz " + + "where mp.code = ?1 or m.code = ?1 " + + "and (?2 is null or (m.storename like %?2% or mp.storename like %?2%))", countQuery = "select count(distinct m) from MerchantStore m left join m.parent mp " + + "where mp.code = ?1 or m.code = ?1 and (?2 is null or (m.storename like %?2% or mp.storename like %?2%))") + Page listChilds(String storeCode, String storeName, Pageable pageable); + + @Query(value = "select * from MERCHANT_STORE m " + "where (m.STORE_CODE = ?1 or (?2 is null or m.PARENT_ID = ?2)) " + + "and (?3 is null or m.STORE_NAME like %?3%)", countQuery = "select count(*) from {h-schema}MERCHANT_STORE m where (m.STORE_CODE = ?1 or (?2 is null or m.PARENT_ID = ?2)) and (?3 is null or m.STORE_NAME like %?3%)", nativeQuery = true) + Page listByGroup(String storeCode, Integer id, String storeName, Pageable pageable); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/OrderRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/OrderRepository.java new file mode 100755 index 0000000000..8b61989bfd --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/OrderRepository.java @@ -0,0 +1,22 @@ +package com.salesmanager.core.business.repositories.order; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.order.Order; + +public interface OrderRepository extends JpaRepository, OrderRepositoryCustom { + + @Query("select o from Order o join fetch o.merchant om " + + "join fetch o.orderProducts op " + + "left join fetch o.delivery od left join fetch od.country left join fetch od.zone " + + "left join fetch o.billing ob left join fetch ob.country left join fetch ob.zone " + + "left join fetch o.orderAttributes oa " + + "join fetch o.orderTotal ot left " + + "join fetch o.orderHistory oh left " + + "join fetch op.downloads opd left " + + "join fetch op.orderAttributes opa " + + "left join fetch op.prices opp where o.id = ?1 and om.id = ?2") + Order findOne(Long id, Integer merchantId); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/OrderRepositoryCustom.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/OrderRepositoryCustom.java new file mode 100755 index 0000000000..c84c618134 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/OrderRepositoryCustom.java @@ -0,0 +1,14 @@ +package com.salesmanager.core.business.repositories.order; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.OrderCriteria; +import com.salesmanager.core.model.order.OrderList; + + + + +public interface OrderRepositoryCustom { + + OrderList listByStore(MerchantStore store, OrderCriteria criteria); + OrderList listOrders(MerchantStore store, OrderCriteria criteria); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/OrderRepositoryImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/OrderRepositoryImpl.java new file mode 100755 index 0000000000..d96548ce34 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/OrderRepositoryImpl.java @@ -0,0 +1,268 @@ +package com.salesmanager.core.business.repositories.order; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; + +import org.apache.commons.lang3.StringUtils; + +import com.salesmanager.core.business.utils.RepositoryHelper; +import com.salesmanager.core.model.common.CriteriaOrderBy; +import com.salesmanager.core.model.common.GenericEntityList; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.OrderCriteria; +import com.salesmanager.core.model.order.OrderList; +import com.salesmanager.core.model.order.orderstatus.OrderStatus; + + +public class OrderRepositoryImpl implements OrderRepositoryCustom { + + + @PersistenceContext + private EntityManager em; + + /** + * @deprecated + */ + @SuppressWarnings("unchecked") + @Override + public OrderList listByStore(MerchantStore store, OrderCriteria criteria) { + + + OrderList orderList = new OrderList(); + StringBuilder countBuilderSelect = new StringBuilder(); + StringBuilder objectBuilderSelect = new StringBuilder(); + + String orderByCriteria = " order by o.id desc"; + + if(criteria.getOrderBy()!=null) { + if(CriteriaOrderBy.ASC.name().equals(criteria.getOrderBy().name())) { + orderByCriteria = " order by o.id asc"; + } + } + + String countBaseQuery = "select count(o) from Order as o"; + String baseQuery = "select o from Order as o left join fetch o.orderTotal ot left join fetch o.orderProducts op left join fetch o.orderAttributes oa left join fetch op.orderAttributes opo left join fetch op.prices opp"; + countBuilderSelect.append(countBaseQuery); + objectBuilderSelect.append(baseQuery); + + + + StringBuilder countBuilderWhere = new StringBuilder(); + StringBuilder objectBuilderWhere = new StringBuilder(); + String whereQuery = " where o.merchant.id=:mId"; + countBuilderWhere.append(whereQuery); + objectBuilderWhere.append(whereQuery); + + + if(!StringUtils.isBlank(criteria.getCustomerName())) { + String nameQuery =" and o.billing.firstName like:nm or o.billing.lastName like:nm"; + countBuilderWhere.append(nameQuery); + objectBuilderWhere.append(nameQuery); + } + + if(!StringUtils.isBlank(criteria.getPaymentMethod())) { + String paymentQuery =" and o.paymentModuleCode like:pm"; + countBuilderWhere.append(paymentQuery); + objectBuilderWhere.append(paymentQuery); + } + + if(criteria.getCustomerId()!=null) { + String customerQuery =" and o.customerId =:cid"; + countBuilderWhere.append(customerQuery); + objectBuilderWhere.append(customerQuery); + } + + objectBuilderWhere.append(orderByCriteria); + + + //count query + Query countQ = em.createQuery( + countBuilderSelect.toString() + countBuilderWhere.toString()); + + //object query + Query objectQ = em.createQuery( + objectBuilderSelect.toString() + objectBuilderWhere.toString()); + + countQ.setParameter("mId", store.getId()); + objectQ.setParameter("mId", store.getId()); + + + if(!StringUtils.isBlank(criteria.getCustomerName())) { + String nameParam = new StringBuilder().append("%").append(criteria.getCustomerName()).append("%").toString(); + countQ.setParameter("nm",nameParam); + objectQ.setParameter("nm",nameParam); + } + + if(!StringUtils.isBlank(criteria.getPaymentMethod())) { + String payementParam = new StringBuilder().append("%").append(criteria.getPaymentMethod()).append("%").toString(); + countQ.setParameter("pm",payementParam); + objectQ.setParameter("pm",payementParam); + } + + if(criteria.getCustomerId()!=null) { + countQ.setParameter("cid", criteria.getCustomerId()); + objectQ.setParameter("cid",criteria.getCustomerId()); + } + + + Number count = (Number) countQ.getSingleResult(); + + orderList.setTotalCount(count.intValue()); + + if(count.intValue()==0) + return orderList; + + //TO BE USED + int max = criteria.getMaxCount(); + int first = criteria.getStartIndex(); + + objectQ.setFirstResult(first); + + + + if(max>0) { + int maxCount = first + max; + + objectQ.setMaxResults(Math.min(maxCount, count.intValue())); + } + + orderList.setOrders(objectQ.getResultList()); + + return orderList; + + + } + + @Override + public OrderList listOrders(MerchantStore store, OrderCriteria criteria) { + OrderList orderList = new OrderList(); + StringBuilder countBuilderSelect = new StringBuilder(); + StringBuilder objectBuilderSelect = new StringBuilder(); + + String orderByCriteria = " order by o.id desc"; + + if(criteria.getOrderBy()!=null) { + if(CriteriaOrderBy.ASC.name().equals(criteria.getOrderBy().name())) { + orderByCriteria = " order by o.id asc"; + } + } + + + String baseQuery = "select o from Order as o left join fetch o.delivery.country left join fetch o.delivery.zone left join fetch o.billing.country left join fetch o.billing.zone left join fetch o.orderTotal ot left join fetch o.orderProducts op left join fetch o.orderAttributes oa left join fetch op.orderAttributes opo left join fetch op.prices opp"; + String countBaseQuery = "select count(o) from Order as o"; + + countBuilderSelect.append(countBaseQuery); + objectBuilderSelect.append(baseQuery); + + StringBuilder objectBuilderWhere = new StringBuilder(); + + String storeQuery =" where o.merchant.code=:mCode"; + objectBuilderWhere.append(storeQuery); + countBuilderSelect.append(storeQuery); + + if(!StringUtils.isEmpty(criteria.getCustomerName())) { + String nameQuery = " and o.billing.firstName like:name or o.billing.lastName like:name"; + objectBuilderWhere.append(nameQuery); + countBuilderSelect.append(nameQuery); + } + + if(!StringUtils.isEmpty(criteria.getEmail())) { + String nameQuery = " and o.customerEmailAddress like:email"; + objectBuilderWhere.append(nameQuery); + countBuilderSelect.append(nameQuery); + } + + //id + if(criteria.getId() != null) { + String nameQuery = " and str(o.id) like:id"; + objectBuilderWhere.append(nameQuery); + countBuilderSelect.append(nameQuery); + } + + //phone + if(!StringUtils.isEmpty(criteria.getCustomerPhone())) { + String nameQuery = " and o.billing.telephone like:phone or o.delivery.telephone like:phone"; + objectBuilderWhere.append(nameQuery); + countBuilderSelect.append(nameQuery); + } + + //status + if(!StringUtils.isEmpty(criteria.getStatus())) { + String nameQuery = " and o.status =:status"; + objectBuilderWhere.append(nameQuery); + countBuilderSelect.append(nameQuery); + } + + objectBuilderWhere.append(orderByCriteria); + + //count query + Query countQ = em.createQuery( + countBuilderSelect.toString()); + + //object query + Query objectQ = em.createQuery( + objectBuilderSelect.toString() + objectBuilderWhere.toString()); + + //customer name + if(!StringUtils.isEmpty(criteria.getCustomerName())) { + countQ.setParameter("name", like(criteria.getCustomerName())); + objectQ.setParameter("name", like(criteria.getCustomerName())); + } + + //email + if(!StringUtils.isEmpty(criteria.getEmail())) { + countQ.setParameter("email", like(criteria.getEmail())); + objectQ.setParameter("email", like(criteria.getEmail())); + } + + //id + if(criteria.getId() != null) { + countQ.setParameter("id", like(String.valueOf(criteria.getId()))); + objectQ.setParameter("id", like(String.valueOf(criteria.getId()))); + } + + //phone + if(!StringUtils.isEmpty(criteria.getCustomerPhone())) { + countQ.setParameter("phone", like(criteria.getCustomerPhone())); + objectQ.setParameter("phone", like(criteria.getCustomerPhone())); + } + + //status + if(!StringUtils.isEmpty(criteria.getStatus())) { + countQ.setParameter("status", OrderStatus.valueOf(criteria.getStatus().toUpperCase())); + objectQ.setParameter("status", OrderStatus.valueOf(criteria.getStatus().toUpperCase())); + } + + + countQ.setParameter("mCode", store.getCode()); + objectQ.setParameter("mCode", store.getCode()); + + + Number count = (Number) countQ.getSingleResult(); + + if(count.intValue()==0) + return orderList; + + @SuppressWarnings("rawtypes") + GenericEntityList entityList = new GenericEntityList(); + entityList.setTotalCount(count.intValue()); + + objectQ = RepositoryHelper.paginateQuery(objectQ, count, entityList, criteria); + + //TODO use GenericEntityList + + orderList.setTotalCount(entityList.getTotalCount()); + orderList.setTotalPages(entityList.getTotalPages()); + + orderList.setOrders(objectQ.getResultList()); + + return orderList; + } + + private String like(String q) { + return '%' + q + '%'; + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/OrderStatusHistoryRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/OrderStatusHistoryRepository.java new file mode 100644 index 0000000000..fb37e9bfa0 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/OrderStatusHistoryRepository.java @@ -0,0 +1,15 @@ +package com.salesmanager.core.business.repositories.order; + +import com.salesmanager.core.model.order.orderstatus.OrderStatusHistory; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface OrderStatusHistoryRepository extends JpaRepository { + + @Query("select osh from OrderStatusHistory osh" + + " join fetch osh.order o" + + " where o.id = ?1 order by osh.dateAdded desc") + List findByOrderId(Long id); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/OrderTotalRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/OrderTotalRepository.java new file mode 100755 index 0000000000..6e5a728418 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/OrderTotalRepository.java @@ -0,0 +1,10 @@ +package com.salesmanager.core.business.repositories.order; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.salesmanager.core.model.order.OrderTotal; + +public interface OrderTotalRepository extends JpaRepository { + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/orderaccount/OrderAccountRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/orderaccount/OrderAccountRepository.java new file mode 100755 index 0000000000..d690b5bfb2 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/orderaccount/OrderAccountRepository.java @@ -0,0 +1,10 @@ +package com.salesmanager.core.business.repositories.order.orderaccount; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.salesmanager.core.model.order.orderaccount.OrderAccount; + +public interface OrderAccountRepository extends JpaRepository { + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/orderproduct/OrderProductDownloadRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/orderproduct/OrderProductDownloadRepository.java new file mode 100755 index 0000000000..02f1890d58 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/orderproduct/OrderProductDownloadRepository.java @@ -0,0 +1,18 @@ +package com.salesmanager.core.business.repositories.order.orderproduct; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.order.orderproduct.OrderProductDownload; + +public interface OrderProductDownloadRepository extends JpaRepository { + + @Query("select o from OrderProductDownload o left join fetch o.orderProduct op join fetch op.order opo join fetch opo.merchant opon where o.id = ?1") + OrderProductDownload findOne(Long id); + + @Query("select o from OrderProductDownload o left join fetch o.orderProduct op join fetch op.order opo join fetch opo.merchant opon where opo.id = ?1") + List findByOrderId(Long id); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/orderproduct/OrderProductRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/orderproduct/OrderProductRepository.java new file mode 100755 index 0000000000..8bddb645f2 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/order/orderproduct/OrderProductRepository.java @@ -0,0 +1,10 @@ +package com.salesmanager.core.business.repositories.order.orderproduct; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.salesmanager.core.model.order.orderproduct.OrderProduct; + +public interface OrderProductRepository extends JpaRepository { + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/payments/TransactionRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/payments/TransactionRepository.java new file mode 100755 index 0000000000..2e2297260e --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/payments/TransactionRepository.java @@ -0,0 +1,22 @@ +package com.salesmanager.core.business.repositories.payments; + +import java.util.Date; +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.jpa.repository.Temporal; +import org.springframework.data.repository.query.Param; + +import com.salesmanager.core.model.payments.Transaction; + +public interface TransactionRepository extends JpaRepository { + + @Query("select t from Transaction t join fetch t.order to where to.id = ?1") + List findByOrder(Long orderId); + + @Query("select t from Transaction t join fetch t.order to left join fetch to.orderAttributes toa left join fetch to.orderProducts too left join fetch to.orderTotal toot left join fetch to.orderHistory tood where to is not null and t.transactionDate BETWEEN :from AND :to") + List findByDates( + @Param("from") @Temporal(javax.persistence.TemporalType.TIMESTAMP) Date startDate, + @Param("to") @Temporal(javax.persistence.TemporalType.TIMESTAMP) Date endDate); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/reference/country/CountryRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/reference/country/CountryRepository.java new file mode 100755 index 0000000000..96fcb9df3f --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/reference/country/CountryRepository.java @@ -0,0 +1,27 @@ +package com.salesmanager.core.business.repositories.reference.country; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.reference.country.Country; + + +public interface CountryRepository extends JpaRepository { + + @Query("select c from Country c left join fetch c.descriptions cd where c.isoCode=?1") + Country findByIsoCode(String code); + + + @Query("select c from Country c " + + "left join fetch c.descriptions cd " + + "left join fetch c.zones cz left join fetch cz.descriptions " + + "where cd.language.id=?1") + List listByLanguage(Integer id); + + /** get country including zones by language **/ + @Query("select distinct c from Country c left join fetch c.descriptions cd left join fetch c.zones cz left join fetch cz.descriptions where cd.language.id=?1") + List listCountryZonesByLanguage(Integer id); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/reference/currency/CurrencyRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/reference/currency/CurrencyRepository.java new file mode 100755 index 0000000000..b23e9ebc34 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/reference/currency/CurrencyRepository.java @@ -0,0 +1,11 @@ +package com.salesmanager.core.business.repositories.reference.currency; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.salesmanager.core.model.reference.currency.Currency; + +public interface CurrencyRepository extends JpaRepository { + + + Currency getByCode(String code); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/reference/language/LanguageRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/reference/language/LanguageRepository.java new file mode 100755 index 0000000000..9426520fe1 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/reference/language/LanguageRepository.java @@ -0,0 +1,14 @@ +package com.salesmanager.core.business.repositories.reference.language; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.reference.language.Language; + +public interface LanguageRepository extends JpaRepository { + + Language findByCode(String code) throws ServiceException; + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/reference/zone/ZoneRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/reference/zone/ZoneRepository.java new file mode 100755 index 0000000000..399dc80923 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/reference/zone/ZoneRepository.java @@ -0,0 +1,21 @@ +package com.salesmanager.core.business.repositories.reference.zone; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.reference.zone.Zone; + +public interface ZoneRepository extends JpaRepository { + + + Zone findByCode(String code); + + @Query("select z from Zone z left join fetch z.descriptions zd where zd.language.id=?1") + List listByLanguage(Integer id); + + @Query("select z from Zone z left join fetch z.descriptions zd join fetch z.country zc where zc.isoCode=?1 and zd.language.id=?2") + List listByLanguageAndCountry(String isoCode, Integer languageId); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/shipping/ShippingOriginRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/shipping/ShippingOriginRepository.java new file mode 100755 index 0000000000..d7b0352619 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/shipping/ShippingOriginRepository.java @@ -0,0 +1,12 @@ +package com.salesmanager.core.business.repositories.shipping; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.shipping.ShippingOrigin; + +public interface ShippingOriginRepository extends JpaRepository { + + @Query("select s from ShippingOrigin as s join fetch s.merchantStore sm where sm.id = ?1") + ShippingOrigin findByStore(Integer storeId); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/shipping/ShippingQuoteRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/shipping/ShippingQuoteRepository.java new file mode 100755 index 0000000000..12737599f7 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/shipping/ShippingQuoteRepository.java @@ -0,0 +1,16 @@ +package com.salesmanager.core.business.repositories.shipping; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.shipping.Quote; + +public interface ShippingQuoteRepository extends JpaRepository { + + + @Query("select q from Quote as q where q.orderId = ?1") + List findByOrder(Long order); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/shoppingcart/ShoppingCartAttributeRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/shoppingcart/ShoppingCartAttributeRepository.java new file mode 100755 index 0000000000..fa95f876d0 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/shoppingcart/ShoppingCartAttributeRepository.java @@ -0,0 +1,9 @@ +package com.salesmanager.core.business.repositories.shoppingcart; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.salesmanager.core.model.shoppingcart.ShoppingCartAttributeItem; +public interface ShoppingCartAttributeRepository extends JpaRepository { + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/shoppingcart/ShoppingCartItemRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/shoppingcart/ShoppingCartItemRepository.java new file mode 100755 index 0000000000..057a1bd0bd --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/shoppingcart/ShoppingCartItemRepository.java @@ -0,0 +1,17 @@ +package com.salesmanager.core.business.repositories.shoppingcart; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +public interface ShoppingCartItemRepository extends JpaRepository { + + @Query("select i from ShoppingCartItem i left join fetch i.attributes ia where i.id = ?1") + ShoppingCartItem findOne(Long id); + + @Modifying + @Query("delete from ShoppingCartItem i where i.id = ?1") + void deleteById(Long id); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/shoppingcart/ShoppingCartRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/shoppingcart/ShoppingCartRepository.java new file mode 100755 index 0000000000..a7dae67a8d --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/shoppingcart/ShoppingCartRepository.java @@ -0,0 +1,26 @@ +package com.salesmanager.core.business.repositories.shoppingcart; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +public interface ShoppingCartRepository extends JpaRepository { + + @Query("select c from ShoppingCart c left join fetch c.lineItems cl left join fetch cl.attributes cla join fetch c.merchantStore cm where c.id = ?1") + ShoppingCart findOne(Long id); + + @Query("select c from ShoppingCart c left join fetch c.lineItems cl left join fetch cl.attributes cla join fetch c.merchantStore cm where c.shoppingCartCode = ?1") + ShoppingCart findByCode(String code); + + @Query("select c from ShoppingCart c left join fetch c.lineItems cl left join fetch cl.attributes cla join fetch c.merchantStore cm where cm.id = ?1 and c.id = ?2") + ShoppingCart findById(Integer merchantId, Long id); + + @Query("select c from ShoppingCart c left join fetch c.lineItems cl left join fetch cl.attributes cla join fetch c.merchantStore cm where cm.id = ?1 and c.shoppingCartCode = ?2") + ShoppingCart findByCode(Integer merchantId, String code); + + @Query("select c from ShoppingCart c left join fetch c.lineItems cl left join fetch cl.attributes cla join fetch c.merchantStore cm where c.customerId = ?1") + List findByCustomer(Long customerId); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/MerchantConfigurationRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/MerchantConfigurationRepository.java new file mode 100755 index 0000000000..b32458c2f8 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/MerchantConfigurationRepository.java @@ -0,0 +1,25 @@ +package com.salesmanager.core.business.repositories.system; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.system.MerchantConfiguration; +import com.salesmanager.core.model.system.MerchantConfigurationType; + +public interface MerchantConfigurationRepository extends JpaRepository { + + //List findByModule(String moduleName); + + //MerchantConfiguration findByCode(String code); + + @Query("select m from MerchantConfiguration m join fetch m.merchantStore ms where ms.id=?1") + List findByMerchantStore(Integer id); + + @Query("select m from MerchantConfiguration m join fetch m.merchantStore ms where ms.id=?1 and m.key=?2") + MerchantConfiguration findByMerchantStoreAndKey(Integer id, String key); + + @Query("select m from MerchantConfiguration m join fetch m.merchantStore ms where ms.id=?1 and m.merchantConfigurationType=?2") + List findByMerchantStoreAndType(Integer id, MerchantConfigurationType type); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/MerchantLogRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/MerchantLogRepository.java new file mode 100755 index 0000000000..db6ba2f874 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/MerchantLogRepository.java @@ -0,0 +1,13 @@ +package com.salesmanager.core.business.repositories.system; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.system.MerchantLog; + +public interface MerchantLogRepository extends JpaRepository { + + List findByStore(MerchantStore store); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/ModuleConfigurationRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/ModuleConfigurationRepository.java new file mode 100755 index 0000000000..8dc1b90de7 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/ModuleConfigurationRepository.java @@ -0,0 +1,16 @@ +package com.salesmanager.core.business.repositories.system; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.salesmanager.core.model.system.IntegrationModule; + +public interface ModuleConfigurationRepository extends JpaRepository { + + List findByModule(String moduleName); + + IntegrationModule findByCode(String code); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/OptinRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/OptinRepository.java new file mode 100755 index 0000000000..f353e9ff58 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/OptinRepository.java @@ -0,0 +1,25 @@ +package com.salesmanager.core.business.repositories.system; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import com.salesmanager.core.model.system.optin.Optin; +import com.salesmanager.core.model.system.optin.OptinType; + +@Repository +public interface OptinRepository extends JpaRepository { + + @Query("select distinct o from Optin as o left join fetch o.merchant om where om.id = ?1") + List findByMerchant(Integer storeId); + + + @Query("select distinct o from Optin as o left join fetch o.merchant om where om.id = ?1 and o.optinType = ?2") + Optin findByMerchantAndType(Integer storeId, OptinType optinTyle); + + @Query("select distinct o from Optin as o left join fetch o.merchant om where om.id = ?1 and o.code = ?2") + Optin findByMerchantAndCode(Integer storeId, String code); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/SystemConfigurationRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/SystemConfigurationRepository.java new file mode 100755 index 0000000000..9958eb6c29 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/SystemConfigurationRepository.java @@ -0,0 +1,12 @@ +package com.salesmanager.core.business.repositories.system; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.salesmanager.core.model.system.SystemConfiguration; + +public interface SystemConfigurationRepository extends JpaRepository { + + + SystemConfiguration findByKey(String key); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/SystemNotificationRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/SystemNotificationRepository.java new file mode 100755 index 0000000000..c92308a318 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/system/SystemNotificationRepository.java @@ -0,0 +1,10 @@ +package com.salesmanager.core.business.repositories.system; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.salesmanager.core.model.system.SystemNotification; + +public interface SystemNotificationRepository extends JpaRepository { + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/tax/TaxClassRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/tax/TaxClassRepository.java new file mode 100755 index 0000000000..3b75e5faed --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/tax/TaxClassRepository.java @@ -0,0 +1,22 @@ +package com.salesmanager.core.business.repositories.tax; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.tax.taxclass.TaxClass; + +public interface TaxClassRepository extends JpaRepository { + + @Query("select t from TaxClass t left join fetch t.merchantStore tm where tm.id=?1") + List findByStore(Integer id); + + @Query("select t from TaxClass t left join fetch t.merchantStore tm where t.code=?1") + TaxClass findByCode(String code); + + @Query("select t from TaxClass t left join fetch t.merchantStore tm where tm.id=?1 and t.code=?2") + TaxClass findByStoreAndCode(Integer id, String code); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/tax/TaxRateRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/tax/TaxRateRepository.java new file mode 100755 index 0000000000..9450958a4d --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/tax/TaxRateRepository.java @@ -0,0 +1,34 @@ +package com.salesmanager.core.business.repositories.tax; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.tax.taxrate.TaxRate; + +public interface TaxRateRepository extends JpaRepository { + + @Query("select t from TaxRate t join fetch t.taxClass join fetch t.merchantStore tm join fetch t.country left join fetch t.zone left join fetch t.descriptions left join t.parent where tm.id=?1 order by t.taxPriority asc") + List findByStore(Integer id); + + @Query("select t from TaxRate t join fetch t.taxClass join fetch t.merchantStore tm join fetch t.country left join fetch t.zone left join fetch t.descriptions td left join t.parent where tm.id=?1 and td.language.id=?2 order by t.taxPriority asc") + List findByStoreAndLanguage(Integer id, Integer languageId); + + @Query("select t from TaxRate t join fetch t.taxClass join fetch t.merchantStore tm join fetch t.country left join fetch t.zone left join fetch t.descriptions td left join t.parent where tm.id=?1 and t.code=?2") + TaxRate findByStoreAndCode(Integer id, String code); + + @Query("select t from TaxRate t join fetch t.taxClass join fetch t.merchantStore tm join fetch t.country left join fetch t.zone left join fetch t.descriptions td left join t.parent where tm.id=?1 and t.id=?2") + TaxRate findByStoreAndId(Integer store, Long id); + + @Query("select t from TaxRate t join fetch t.taxClass join fetch t.merchantStore tm join fetch t.country left join fetch t.zone left join fetch t.descriptions td left join t.parent where t.id=?1") + TaxRate findOne(Long id); + + @Query("select t from TaxRate t join fetch t.taxClass join fetch t.merchantStore tm join fetch t.country tc left join fetch t.zone tz left join fetch t.descriptions td left join t.parent where tm.id=?1 AND (tz.id=?2 OR tz IS NULL) and tc.id=?3 and td.language.id=?4 order by t.taxPriority asc") + List findByMerchantAndZoneAndCountryAndLanguage(Integer id, Long zoneId, Integer countryId, Integer languageId); + + @Query("select t from TaxRate t join fetch t.taxClass join fetch t.merchantStore tm join fetch t.country tc left join fetch t.zone tz left join fetch t.descriptions td left join t.parent where tm.id=?1 AND t.stateProvince=?2 and tc.id=?3 and td.language.id=?4 order by t.taxPriority asc") + List findByMerchantAndProvinceAndCountryAndLanguage(Integer id, String province, Integer countryId, Integer languageId); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/GroupRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/GroupRepository.java new file mode 100755 index 0000000000..b946e67e9b --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/GroupRepository.java @@ -0,0 +1,34 @@ +package com.salesmanager.core.business.repositories.user; + +import java.util.List; +import java.util.Set; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.model.user.GroupType; + +public interface GroupRepository extends JpaRepository { + + + Group findById(Long id); + + @Query("select distinct g from Group as g left join fetch g.permissions perms order by g.id") + List findAll(); + + @Query("select distinct g from Group as g left join fetch g.permissions perms where perms.id in (?1) ") + List findByPermissions(Set permissionIds); + + @Query("select distinct g from Group as g left join fetch g.permissions perms where g.id in (?1) ") + List findByIds(Set groupIds); + + @Query("select distinct g from Group as g left join fetch g.permissions perms where g.groupName in (?1) ") + List findByNames(List groupeNames); + + @Query("select distinct g from Group as g left join fetch g.permissions perms where g.groupType = ?1") + List findByType(GroupType type); + + @Query("select g from Group as g left join fetch g.permissions perms where g.groupName =?1") + Group findByGroupName(String name); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/PageableUserRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/PageableUserRepository.java new file mode 100644 index 0000000000..8a8ddc1f1e --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/PageableUserRepository.java @@ -0,0 +1,27 @@ +package com.salesmanager.core.business.repositories.user; + +import java.util.List; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.PagingAndSortingRepository; + +import com.salesmanager.core.model.user.User; + +public interface PageableUserRepository extends PagingAndSortingRepository { + + @Query(value = "select distinct u from User as u left join fetch u.groups ug left join fetch ug.permissions ugp left join fetch u.defaultLanguage ud join fetch u.merchantStore um where um.code=?1 and (?2 is null or u.adminEmail like %?2%)", + countQuery = "select count(distinct u) from User as u join u.groups ug join ug.permissions ugp join u.merchantStore um where um.code=?1 and (?2 is null or u.adminEmail like %?2%)") + Page listByStore(String store, String email, Pageable pageable); + + @Query(value = "select distinct u from User as u left join fetch u.groups ug left join fetch ug.permissions ugp left join fetch u.defaultLanguage ud join fetch u.merchantStore um where (?1 is null or u.adminEmail like %?1%)", + countQuery = "select count(distinct u) from User as u join u.groups ug join ug.permissions ugp join u.merchantStore um where (?1 is null or u.adminEmail like %?1%)") + Page listAll(String email, Pageable pageable); + + @Query(value = "select distinct u from User as u left join fetch u.groups ug left join fetch ug.permissions ugp left join fetch u.defaultLanguage ud join fetch u.merchantStore um where um.id in ?1 and (?2 is null or u.adminEmail like %?2%)", + countQuery = "select count(distinct u) from User as u join u.groups ug join ug.permissions ugp join u.merchantStore um where um.id in ?1 and (?2 is null or u.adminEmail like %?2%)") + Page listByStoreIds(List stores, String email, Pageable pageable); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/PermissionRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/PermissionRepository.java new file mode 100755 index 0000000000..5e8087ced2 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/PermissionRepository.java @@ -0,0 +1,22 @@ +package com.salesmanager.core.business.repositories.user; + +import java.util.List; +import java.util.Set; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.user.Permission; + +public interface PermissionRepository extends JpaRepository, PermissionRepositoryCustom { + + + @Query("select p from Permission as p where p.id = ?1") + Permission findOne(Integer id); + + @Query("select p from Permission as p order by p.id") + List findAll(); + + @Query("select distinct p from Permission as p join fetch p.groups groups where groups.id in (?1)") + List findByGroups(Set groupIds); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/PermissionRepositoryCustom.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/PermissionRepositoryCustom.java new file mode 100755 index 0000000000..00cdee7433 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/PermissionRepositoryCustom.java @@ -0,0 +1,14 @@ +package com.salesmanager.core.business.repositories.user; + +import com.salesmanager.core.model.user.PermissionCriteria; +import com.salesmanager.core.model.user.PermissionList; + + + + +public interface PermissionRepositoryCustom { + + PermissionList listByCriteria(PermissionCriteria criteria); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/PermissionRepositoryImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/PermissionRepositoryImpl.java new file mode 100755 index 0000000000..22f0932882 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/PermissionRepositoryImpl.java @@ -0,0 +1,94 @@ +package com.salesmanager.core.business.repositories.user; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + + +import javax.persistence.Query; + +import com.salesmanager.core.model.user.Permission; +import com.salesmanager.core.model.user.PermissionCriteria; +import com.salesmanager.core.model.user.PermissionList; + + +public class PermissionRepositoryImpl implements PermissionRepositoryCustom { + + + @PersistenceContext + private EntityManager em; + + @Override + public PermissionList listByCriteria(PermissionCriteria criteria) { + PermissionList permissionList = new PermissionList(); + + + StringBuilder countBuilderSelect = new StringBuilder(); + countBuilderSelect.append("select count(p) from Permission as p"); + + StringBuilder countBuilderWhere = new StringBuilder(); + + + if(criteria.getGroupIds()!=null && criteria.getGroupIds().size()>0) { + countBuilderSelect.append(" INNER JOIN p.groups grous"); + countBuilderWhere.append(" where grous.id in (:cid)"); + } + + + Query countQ = em.createQuery( + countBuilderSelect.toString() + countBuilderWhere.toString()); + + if(criteria.getGroupIds()!=null && criteria.getGroupIds().size()>0) { + countQ.setParameter("cid", criteria.getGroupIds()); + } + + + Number count = (Number) countQ.getSingleResult (); + + permissionList.setTotalCount(count.intValue()); + + if(count.intValue()==0) + return permissionList; + + + StringBuilder qs = new StringBuilder(); + qs.append("select p from Permission as p "); + qs.append("join fetch p.groups grous "); + + if(criteria.getGroupIds()!=null && criteria.getGroupIds().size()>0) { + qs.append(" where grous.id in (:cid)"); + } + + qs.append(" order by p.id asc "); + + String hql = qs.toString(); + Query q = em.createQuery(hql); + + + if(criteria.getGroupIds()!=null && criteria.getGroupIds().size()>0) { + q.setParameter("cid", criteria.getGroupIds()); + } + + if(criteria.getMaxCount()>0) { + + + q.setFirstResult(criteria.getStartIndex()); + if(criteria.getMaxCount() permissions = q.getResultList(); + permissionList.setPermissions(permissions); + + return permissionList; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/UserRepository.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/UserRepository.java new file mode 100755 index 0000000000..bfd4657429 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/UserRepository.java @@ -0,0 +1,39 @@ +package com.salesmanager.core.business.repositories.user; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.salesmanager.core.model.user.User; + +public interface UserRepository extends JpaRepository, UserRepositoryCustom { + + @Query("select distinct u from User as u left join fetch u.groups ug left join fetch ug.permissions ugp join fetch u.merchantStore um left join fetch u.defaultLanguage ul where u.adminName = ?1") + User findByUserName(String userName); + + @Query("select distinct u from User as u left join fetch u.groups ug join fetch u.merchantStore um left join fetch u.defaultLanguage ul where u.id = ?1 and um.code = ?2") + User findByUserId(Long userId, String storeCode); + + @Query("select distinct u from User as u left join fetch u.groups ug join fetch u.merchantStore um left join fetch u.defaultLanguage ul where u.adminName= ?1 and um.code = ?2") + User findByUserName(String userName, String storeCode); + + @Query("select distinct u from User as u left join fetch u.groups ug join fetch u.merchantStore um left join fetch u.defaultLanguage ul where u.id = ?1") + User findOne(Long id); + + @Query("select distinct u from User as u left join fetch u.groups ug join fetch u.merchantStore um left join fetch u.defaultLanguage ul order by u.id") + List findAll(); + + @Query("select distinct u from User as u left join fetch u.groups ug join fetch u.merchantStore um left join fetch u.defaultLanguage ul where um.id = ?1 order by u.id") + List findByStore(Integer storeId); + + @Query("select distinct u from User as u left join fetch u.groups ug join fetch u.merchantStore um left join fetch u.defaultLanguage ul where u.id= ?1 and um.code = ?2") + User findByUserAndStore(Long userId, String storeCode); + + @Query("select distinct u from User as u " + + "left join fetch u.groups ug " + + "join fetch u.merchantStore um " + + "left join fetch u.defaultLanguage ul " + + "where u.credentialsResetRequest.credentialsRequest = ?1 and um.code = ?2 ") + User findByResetPasswordToken(String token, String store); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/UserRepositoryCustom.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/UserRepositoryCustom.java new file mode 100755 index 0000000000..ec1d4691be --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/UserRepositoryCustom.java @@ -0,0 +1,12 @@ +package com.salesmanager.core.business.repositories.user; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.common.Criteria; +import com.salesmanager.core.model.common.GenericEntityList; +import com.salesmanager.core.model.user.User; + +public interface UserRepositoryCustom { + + GenericEntityList listByCriteria(Criteria criteria) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/UserRepositoryImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/UserRepositoryImpl.java new file mode 100755 index 0000000000..d643993d96 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/repositories/user/UserRepositoryImpl.java @@ -0,0 +1,104 @@ +package com.salesmanager.core.business.repositories.user; + +import java.util.List; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.utils.RepositoryHelper; +import com.salesmanager.core.model.common.Criteria; +import com.salesmanager.core.model.common.GenericEntityList; +import com.salesmanager.core.model.user.User; + +public class UserRepositoryImpl implements UserRepositoryCustom { + + + @PersistenceContext + private EntityManager em; + + private static final Logger LOGGER = LoggerFactory.getLogger(UserRepositoryImpl.class); + + @SuppressWarnings("unchecked") + @Override + public GenericEntityList listByCriteria(Criteria criteria) throws ServiceException { + + /** + * Name like + * email like + */ + + + try { + StringBuilder req = new StringBuilder(); + req.append( + "select distinct u from User as u left join fetch u.groups ug left join fetch u.defaultLanguage ud join fetch u.merchantStore um"); + StringBuilder countBuilder = new StringBuilder(); + countBuilder.append("select count(distinct u) from User as u join u.merchantStore um"); + if (!StringUtils.isBlank(criteria.getStoreCode())) { + req.append(" where um.code=:storeCode"); + countBuilder.append(" where um.code=:storeCode"); + } + + if(!StringUtils.isBlank(criteria.getCriteriaOrderByField())) { + req.append(" order by u." + criteria.getCriteriaOrderByField() + " " + + criteria.getOrderBy().name().toLowerCase()); + } + + Query countQ = this.em.createQuery(countBuilder.toString()); + + String hql = req.toString(); + Query q = this.em.createQuery(hql); + + if(!StringUtils.isBlank(criteria.getSearch())) { + //TODO + } else { + if (criteria.getStoreCode() != null) { + countQ.setParameter("storeCode", criteria.getStoreCode()); + q.setParameter("storeCode", criteria.getStoreCode()); + } + } + + Number count = (Number) countQ.getSingleResult(); + + @SuppressWarnings("rawtypes") + GenericEntityList entityList = new GenericEntityList(); + entityList.setTotalCount(count.intValue()); + + /** + * Configure pagination using setMaxResults and setFirstResult method + */ + + q = RepositoryHelper.paginateQuery(q, count, entityList, criteria); + +/* if(criteria.isLegacyPagination()) { + if (criteria.getMaxCount() > 0) { + q.setFirstResult(criteria.getStartIndex()); + if (criteria.getMaxCount() < count.intValue()) { + q.setMaxResults(criteria.getMaxCount()); + } else { + q.setMaxResults(count.intValue()); + } + } + } else { + + }*/ + + List users = q.getResultList(); + entityList.setList(users); + + return entityList; + + + + } catch (javax.persistence.NoResultException ers) { + } catch (Exception e) { + LOGGER.error(e.getMessage()); + throw new ServiceException(e); + } + return null; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/catalog/CatalogEntryService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/catalog/CatalogEntryService.java new file mode 100644 index 0000000000..edf29f955d --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/catalog/CatalogEntryService.java @@ -0,0 +1,21 @@ +package com.salesmanager.core.business.services.catalog.catalog; + +import org.springframework.data.domain.Page; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.catalog.Catalog; +import com.salesmanager.core.model.catalog.catalog.CatalogCategoryEntry; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +public interface CatalogEntryService extends SalesManagerEntityService { + + + void add (CatalogCategoryEntry entry, Catalog catalog); + + void remove (CatalogCategoryEntry catalogEntry) throws ServiceException; + + Page list(Catalog catalog, MerchantStore store, Language language, String name, int page, int count); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/catalog/CatalogEntryServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/catalog/CatalogEntryServiceImpl.java new file mode 100644 index 0000000000..61d84d9d41 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/catalog/CatalogEntryServiceImpl.java @@ -0,0 +1,57 @@ +package com.salesmanager.core.business.services.catalog.catalog; + +import javax.inject.Inject; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.catalog.catalog.CatalogEntryRepository; +import com.salesmanager.core.business.repositories.catalog.catalog.PageableCatalogEntryRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.catalog.Catalog; +import com.salesmanager.core.model.catalog.catalog.CatalogCategoryEntry; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +@Service("catalogEntryService") +public class CatalogEntryServiceImpl extends SalesManagerEntityServiceImpl +implements CatalogEntryService { + + @Autowired + private PageableCatalogEntryRepository pageableCatalogEntryRepository; + + private CatalogEntryRepository catalogEntryRepository; + + @Inject + public CatalogEntryServiceImpl(CatalogEntryRepository repository) { + super(repository); + this.catalogEntryRepository = repository; + } + + @Override + public void add(CatalogCategoryEntry entry, Catalog catalog) { + entry.setCatalog(catalog); + catalogEntryRepository.save(entry); + } + + + @Override + public Page list(Catalog catalog, MerchantStore store, Language language, String name, int page, + int count) { + Pageable pageRequest = PageRequest.of(page, count); + return pageableCatalogEntryRepository.listByCatalog(catalog.getId(), store.getId(), language.getId(), name, pageRequest); + + } + + @Override + public void remove(CatalogCategoryEntry catalogEntry) throws ServiceException { + catalogEntryRepository.delete(catalogEntry); + + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/catalog/CatalogService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/catalog/CatalogService.java new file mode 100755 index 0000000000..93ca67a33d --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/catalog/CatalogService.java @@ -0,0 +1,43 @@ +package com.salesmanager.core.business.services.catalog.catalog; + +import org.springframework.data.domain.Page; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.catalog.Catalog; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +import java.util.Optional; + +public interface CatalogService extends SalesManagerEntityService { + + + /** + * Creates a new Catalog + * @param store + * @return Catalog + * @throws ServiceException + */ + Catalog saveOrUpdate(Catalog catalog, MerchantStore store); + + Optional getById(Long catalogId, MerchantStore store); + + Optional getByCode(String code, MerchantStore store); + + /** + * Get a list of Catalog associated with a MarketPlace + * @param marketPlace + * @return List + * @throws ServiceException + */ + Page getCatalogs(MerchantStore store, Language language, String name, int page, int count); + + /** + * Delete a Catalog and related objects + */ + void delete(Catalog catalog) throws ServiceException; + + boolean existByCode(String code, MerchantStore store); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/catalog/CatalogServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/catalog/CatalogServiceImpl.java new file mode 100644 index 0000000000..4af2d851ed --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/catalog/CatalogServiceImpl.java @@ -0,0 +1,74 @@ +package com.salesmanager.core.business.services.catalog.catalog; + +import javax.inject.Inject; + +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.catalog.catalog.CatalogRepository; +import com.salesmanager.core.business.repositories.catalog.catalog.PageableCatalogRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.catalog.Catalog; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +import java.util.Optional; + +@Service("catalogService") +public class CatalogServiceImpl +extends SalesManagerEntityServiceImpl +implements CatalogService { + + + private CatalogRepository catalogRepository; + + @Autowired + private PageableCatalogRepository pageableCatalogRepository; + + @Inject + public CatalogServiceImpl(CatalogRepository repository) { + super(repository); + this.catalogRepository = repository; + } + + @Override + public Catalog saveOrUpdate(Catalog catalog, MerchantStore store) { + catalogRepository.save(catalog); + return catalog; + } + + @Override + public Page getCatalogs(MerchantStore store, Language language, String name, int page, int count) { + Pageable pageRequest = PageRequest.of(page, count); + return pageableCatalogRepository.listByStore(store.getId(), name, pageRequest); + } + + @Override + public void delete(Catalog catalog) throws ServiceException { + Validate.notNull(catalog,"Catalog must not be null"); + catalogRepository.delete(catalog); + } + + @Override + public Optional getById(Long catalogId, MerchantStore store) { + return catalogRepository.findById(catalogId, store.getId()); + } + + @Override + public Optional getByCode(String code, MerchantStore store) { + return catalogRepository.findByCode(code, store.getId()); + } + + @Override + public boolean existByCode(String code, MerchantStore store) { + return catalogRepository.existsByCode(code, store.getId()); + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/category/CategoryService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/category/CategoryService.java new file mode 100755 index 0000000000..0d2e6f1a70 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/category/CategoryService.java @@ -0,0 +1,131 @@ +package com.salesmanager.core.business.services.catalog.category; + +import java.util.List; +import org.springframework.data.domain.Page; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.category.CategoryDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +public interface CategoryService extends SalesManagerEntityService { + + List getListByLineage(MerchantStore store, String lineage) throws ServiceException; + + List listBySeUrl(MerchantStore store, String seUrl) throws ServiceException; + + CategoryDescription getDescription(Category category, Language language) throws ServiceException; + + void addCategoryDescription(Category category, CategoryDescription description) throws ServiceException; + + void addChild(Category parent, Category child) throws ServiceException; + + List listByParent(Category category) throws ServiceException; + + List listByStoreAndParent(MerchantStore store, Category category) throws ServiceException; + + + List getByName(MerchantStore store, String name, Language language) throws ServiceException; + + List listByStore(MerchantStore store) throws ServiceException; + + Category getByCode(MerchantStore store, String code) + throws ServiceException; + + List listByStore(MerchantStore store, Language language) + throws ServiceException; + + void saveOrUpdate(Category category) throws ServiceException; + + List getListByDepth(MerchantStore store, int depth); + + Category getById(Long id, int merchantId); + + Category getById(Long categoryid, int merchantId, int language); + + Page getListByDepth(MerchantStore store, Language language, String name, int depth, int page, int count); + + /** + * Get root categories by store for a given language + * @param store + * @param depth + * @param language + * @return + */ + List getListByDepth(MerchantStore store, int depth, Language language); + + /** + * Returns category hierarchy filter by featured + * @param store + * @param depth + * @param language + * @return + */ + List getListByDepthFilterByFeatured(MerchantStore store, int depth, Language language); + + List getListByLineage(String storeCode, String lineage) + throws ServiceException; + + Category getByCode(String storeCode, String code) throws ServiceException; + + Category getById(MerchantStore store, Long id) throws ServiceException; + + Category getBySeUrl(MerchantStore store, String seUrl); + + List listByParent(Category category, Language language); + + Category getOneByLanguage(long categoryId, Language language); + + /** + * Returns a list by category containing the category code and the number of products + * 1->obj[0] = 1 + * obj[1] = 150 + * 2->obj[0] = 2 + * obj[1] = 35 + * ... + * @param store + * @param categoryIds + * @return + * @throws ServiceException + */ + List countProductsByCategories(MerchantStore store, + List categoryIds) throws ServiceException; + + List getByProductId(Long productId, MerchantStore store); + + /** + * Returns a list of Category by category code for a given language + * @param store + * @param codes + * @param language + * @return + */ + List listByCodes(MerchantStore store, List codes, + Language language); + + /** + * List of Category by id + * @param store + * @param ids + * @param language + * @return + */ + List listByIds(MerchantStore store, List ids, + Language language); + + + /** + * Returns Category with childs and descriptions + * @param category + * @return + */ + Category findById(Long category); + + int count(MerchantStore store); + + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/category/CategoryServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/category/CategoryServiceImpl.java new file mode 100755 index 0000000000..5622562c4d --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/category/CategoryServiceImpl.java @@ -0,0 +1,431 @@ +package com.salesmanager.core.business.services.catalog.category; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import javax.inject.Inject; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.util.Assert; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.catalog.category.CategoryDescriptionRepository; +import com.salesmanager.core.business.repositories.catalog.category.CategoryRepository; +import com.salesmanager.core.business.repositories.catalog.category.PageableCategoryRepository; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.category.CategoryDescription; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +@Service("categoryService") +public class CategoryServiceImpl extends SalesManagerEntityServiceImpl implements CategoryService { + + + private CategoryRepository categoryRepository; + + @Inject + private ProductService productService; + + @Inject + private PageableCategoryRepository pageableCategoryRepository; + + @Inject + private CategoryDescriptionRepository categoryDescriptionRepository; + + + + @Inject + public CategoryServiceImpl(CategoryRepository categoryRepository) { + super(categoryRepository); + this.categoryRepository = categoryRepository; + } + + public void create(Category category) throws ServiceException { + + super.create(category); + StringBuilder lineage = new StringBuilder(); + Category parent = category.getParent(); + if (parent != null && parent.getId() != null && parent.getId() != 0) { + //get parent category + Category p = this.getById(parent.getId()); + + lineage.append(p.getLineage()).append(category.getId()).append("/"); + category.setDepth(p.getDepth() + 1); + } else { + lineage.append("/").append(category.getId()).append("/"); + category.setDepth(0); + } + category.setLineage(lineage.toString()); + super.update(category); + + + } + + @Override + public List countProductsByCategories(MerchantStore store, List categoryIds) + throws ServiceException { + + return categoryRepository.countProductsByCategories(store, categoryIds); + + } + + + @Override + public List listByCodes(MerchantStore store, List codes, Language language) { + return categoryRepository.findByCodes(store.getId(), codes, language.getId()); + } + + @Override + public List listByIds(MerchantStore store, List ids, Language language) { + return categoryRepository.findByIds(store.getId(), ids, language.getId()); + } + + @Override + public Category getOneByLanguage(long categoryId, Language language) { + return categoryRepository.findByIdAndLanguage(categoryId, language.getId()); + } + + @Override + public void saveOrUpdate(Category category) throws ServiceException { + + // save or update (persist and attach entities + if (category.getId() != null && category.getId() > 0) { + super.update(category); + } else { + this.create(category); + } + + } + + @Override + public List getListByLineage(MerchantStore store, String lineage) throws ServiceException { + try { + return categoryRepository.findByLineage(store.getId(), lineage); + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + @Override + public List getListByLineage(String storeCode, String lineage) throws ServiceException { + try { + return categoryRepository.findByLineage(storeCode, lineage); + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + @Override + public List listBySeUrl(MerchantStore store, String seUrl) throws ServiceException { + + try { + return categoryRepository.listByFriendlyUrl(store.getId(), seUrl); + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + @Override + public Category getBySeUrl(MerchantStore store, String seUrl) { + return categoryRepository.findByFriendlyUrl(store.getId(), seUrl); + } + + @Override + public Category getByCode(MerchantStore store, String code) throws ServiceException { + + try { + return categoryRepository.findByCode(store.getId(), code); + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + @Override + public Category getByCode(String storeCode, String code) throws ServiceException { + + try { + return categoryRepository.findByCode(storeCode, code); + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + @Override + public Category getById(Long id, int merchantId) { + + Category category = categoryRepository.findByIdAndStore(id, merchantId); + + if(category == null) { + return null; + } + + List descriptions = categoryDescriptionRepository.listByCategoryId(id); + Set desc = new HashSet(descriptions); + category.setDescriptions(desc); + + return category; + + } + + @Override + public List listByParent(Category category) throws ServiceException { + + try { + return categoryRepository.listByStoreAndParent(null, category); + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + @Override + public List listByStoreAndParent(MerchantStore store, Category category) throws ServiceException { + + try { + return categoryRepository.listByStoreAndParent(store, category); + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + @Override + public List listByParent(Category category, Language language) { + Assert.notNull(category, "Category cannot be null"); + Assert.notNull(language, "Language cannot be null"); + Assert.notNull(category.getMerchantStore(), "category.merchantStore cannot be null"); + + return categoryRepository.findByParent(category.getId(), language.getId()); + } + + @Override + public void addCategoryDescription(Category category, CategoryDescription description) throws ServiceException { + + try { + category.getDescriptions().add(description); + description.setCategory(category); + update(category); + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + // @Override + public void delete(Category category) throws ServiceException { + + // get category with lineage (subcategories) + StringBuilder lineage = new StringBuilder(); + lineage.append(category.getLineage()).append(category.getId()).append(Constants.SLASH); + List categories = this.getListByLineage(category.getMerchantStore(), lineage.toString()); + + Category dbCategory = getById(category.getId(), category.getMerchantStore().getId()); + + if (dbCategory != null && dbCategory.getId().longValue() == category.getId().longValue()) { + + categories.add(dbCategory); + + Collections.reverse(categories); + + List categoryIds = new ArrayList(); + + for (Category c : categories) { + categoryIds.add(c.getId()); + } + + List products = productService.getProducts(categoryIds); + // org.hibernate.Session session = + // em.unwrap(org.hibernate.Session.class);// need to refresh the + // session to update + // all product + // categories + + for (Product product : products) { + // session.evict(product);// refresh product so we get all + // product categories + Product dbProduct = productService.getById(product.getId()); + Set productCategories = dbProduct.getCategories(); + if (productCategories.size() > 1) { + for (Category c : categories) { + productCategories.remove(c); + productService.update(dbProduct); + } + + if (product.getCategories() == null || product.getCategories().size() == 0) { + productService.delete(dbProduct); + } + + } else { + productService.delete(dbProduct); + } + + } + + Category categ = getById(category.getId(), category.getMerchantStore().getId()); + categoryRepository.delete(categ); + + } + + } + + @Override + public CategoryDescription getDescription(Category category, Language language) { + + for (CategoryDescription description : category.getDescriptions()) { + if (description.getLanguage().equals(language)) { + return description; + } + } + return null; + } + + @Override + public void addChild(Category parent, Category child) throws ServiceException { + + if (child == null || child.getMerchantStore() == null) { + throw new ServiceException("Child category and merchant store should not be null"); + } + + try { + + if (parent == null) { + + // assign to root + child.setParent(null); + child.setDepth(0); + // child.setLineage(new + // StringBuilder().append("/").append(child.getId()).append("/").toString()); + child.setLineage(new StringBuilder().append("/").append(child.getId()).append("/").toString()); + + } else { + + Category p = getById(parent.getId(), parent.getMerchantStore().getId());// parent + + String lineage = p.getLineage(); + int depth = p.getDepth(); + + child.setParent(p); + child.setDepth(depth + 1); + child.setLineage(new StringBuilder().append(lineage).append(Constants.SLASH).append(child.getId()) + .append(Constants.SLASH).toString()); + + } + + update(child); + StringBuilder childLineage = new StringBuilder(); + childLineage.append(child.getLineage()).append(child.getId()).append("/"); + List subCategories = getListByLineage(child.getMerchantStore(), childLineage.toString()); + + // ajust all sub categories lineages + if (subCategories != null && subCategories.size() > 0) { + for (Category subCategory : subCategories) { + if (!child.getId().equals(subCategory.getId())) { + addChild(child, subCategory); + } + } + + } + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + @Override + public List getListByDepth(MerchantStore store, int depth) { + return categoryRepository.findByDepth(store.getId(), depth); + } + + @Override + public List getListByDepthFilterByFeatured(MerchantStore store, int depth, Language language) { + return categoryRepository.findByDepthFilterByFeatured(store.getId(), depth, language.getId()); + } + + @Override + public List getByName(MerchantStore store, String name, Language language) throws ServiceException { + + try { + return categoryRepository.findByName(store.getId(), name, language.getId()); + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + @Override + public List listByStore(MerchantStore store) throws ServiceException { + + try { + return categoryRepository.findByStore(store.getId()); + } catch (Exception e) { + throw new ServiceException(e); + } + } + + @Override + public List listByStore(MerchantStore store, Language language) throws ServiceException { + + try { + return categoryRepository.findByStore(store.getId(), language.getId()); + } catch (Exception e) { + throw new ServiceException(e); + } + } + + @Override + public Category getById(MerchantStore store, Long id) throws ServiceException { + return categoryRepository.findById(id, store.getCode()); + } + + @Override + public Category findById(Long category) { + Optional cat = categoryRepository.findById(category); + return cat.orElse(null); + } + + @Override + public Page getListByDepth(MerchantStore store, Language language, String name, int depth, int page, + int count) { + + Pageable pageRequest = PageRequest.of(page, count); + + return pageableCategoryRepository.listByStore(store.getId(), language.getId(), name, pageRequest); + } + + @Override + public List getListByDepth(MerchantStore store, int depth, Language language) { + return categoryRepository.find(store.getId(), depth, language.getId(), null); + } + + @Override + public int count(MerchantStore store) { + return categoryRepository.count(store.getId()); + } + + @Override + public Category getById(Long categoryid, int merchantId, int language) { + return categoryRepository.findById(merchantId, categoryid, language); + } + + @Override + public List getByProductId(Long productId, MerchantStore store) { + return categoryRepository.listByProduct(store, productId); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/inventory/ProductInventoryService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/inventory/ProductInventoryService.java new file mode 100644 index 0000000000..af5341f30e --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/inventory/ProductInventoryService.java @@ -0,0 +1,14 @@ +package com.salesmanager.core.business.services.catalog.inventory; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.inventory.ProductInventory; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; + +public interface ProductInventoryService { + + + ProductInventory inventory(Product product) throws ServiceException; + ProductInventory inventory(ProductVariant variant) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/inventory/ProductInventoryServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/inventory/ProductInventoryServiceImpl.java new file mode 100644 index 0000000000..f5742b2eca --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/inventory/ProductInventoryServiceImpl.java @@ -0,0 +1,85 @@ +package com.salesmanager.core.business.services.catalog.inventory; + +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.inventory.ProductInventory; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; + + +@Service("inventoryService") +public class ProductInventoryServiceImpl implements ProductInventoryService { + + + @Autowired + private PricingService pricingService; + + @Override + public ProductInventory inventory(Product product) throws ServiceException { + Validate.notNull(product.getAvailabilities()); + + ProductAvailability availability = defaultAvailability(product.getAvailabilities()); + FinalPrice finalPrice = pricingService.calculateProductPrice(product); + + ProductInventory inventory = inventory(availability, finalPrice); + inventory.setSku(product.getSku()); + return inventory; + } + + @Override + public ProductInventory inventory(ProductVariant variant) throws ServiceException { + Validate.notNull(variant.getAvailabilities()); + Validate.notNull(variant.getProduct()); + + ProductAvailability availability = null; + if(!CollectionUtils.isEmpty(variant.getAvailabilities())) { + availability = defaultAvailability(variant.getAvailabilities()); + } else { + availability = defaultAvailability(variant.getProduct().getAvailabilities()); + } + FinalPrice finalPrice = pricingService.calculateProductPrice(variant); + + if(finalPrice==null) { + finalPrice = pricingService.calculateProductPrice(variant.getProduct()); + } + + ProductInventory inventory = inventory(availability, finalPrice); + inventory.setSku(variant.getSku()); + return inventory; + } + + private ProductAvailability defaultAvailability(Set availabilities) { + + ProductAvailability defaultAvailability = availabilities.iterator().next(); + + for (ProductAvailability availability : availabilities) { + if (!StringUtils.isEmpty(availability.getRegion()) + && availability.getRegion().equals(Constants.ALL_REGIONS)) {// TODO REL 2.1 accept a region + defaultAvailability = availability; + } + } + + return defaultAvailability; + + } + + private ProductInventory inventory(ProductAvailability availability, FinalPrice price) { + ProductInventory inventory = new ProductInventory(); + inventory.setQuantity(availability.getProductQuantity()); + inventory.setPrice(price); + + return inventory; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/marketplace/MarketPlaceService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/marketplace/MarketPlaceService.java new file mode 100755 index 0000000000..2e7d68806f --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/marketplace/MarketPlaceService.java @@ -0,0 +1,30 @@ +package com.salesmanager.core.business.services.catalog.marketplace; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.marketplace.MarketPlace; +import com.salesmanager.core.model.merchant.MerchantStore; + +public interface MarketPlaceService extends SalesManagerEntityService { + + /** + * Creates a MarketPlace + * @param store + * @param code + * @return MarketPlace + * @throws ServiceException + */ + MarketPlace create(MerchantStore store, String code) throws ServiceException; + + /** + * Fetch a specific marketplace + * @param store + * @param code + * @return MarketPlace + * @throws ServiceException + */ + MarketPlace getByCode(MerchantStore store, String code) throws ServiceException; + + void delete(MarketPlace marketPlace) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/pricing/PricingService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/pricing/PricingService.java new file mode 100755 index 0000000000..6eb0bdcc7b --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/pricing/PricingService.java @@ -0,0 +1,137 @@ +package com.salesmanager.core.business.services.catalog.pricing; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.currency.Currency; + + +/** + * Services for Product item price calculation. + * @author Carl Samson + * + */ +public interface PricingService { + + /** + * Calculates the FinalPrice of a Product taking into account + * all defined prices and possible rebates + * @param product + * @return + * @throws ServiceException + */ + FinalPrice calculateProductPrice(Product product) throws ServiceException; + + /** + * Calculates variant price specific to variant inventory or parent inventory + * @param variant + * @return + * @throws ServiceException + */ + FinalPrice calculateProductPrice(ProductVariant variant) throws ServiceException; + + /** + * Calculates the price on a specific inventory + * @param product + * @return + * @throws ServiceException + */ + FinalPrice calculateProductPrice(ProductAvailability product) throws ServiceException; + + /** + * Calculates the FinalPrice of a Product taking into account + * all defined prices and possible rebates. It also applies other calculation + * based on the customer + * @param product + * @param customer + * @return + * @throws ServiceException + */ + FinalPrice calculateProductPrice(Product product, Customer customer) + throws ServiceException; + + /** + * Calculates the FinalPrice of a Product taking into account + * all defined prices and possible rebates. This method should be used to calculate + * any additional prices based on the default attributes or based on the user selected attributes. + * @param product + * @param attributes + * @return + * @throws ServiceException + */ + FinalPrice calculateProductPrice(Product product, + List attributes) throws ServiceException; + + /** + * Calculates the FinalPrice of a Product taking into account + * all defined prices and possible rebates. This method should be used to calculate + * any additional prices based on the default attributes or based on the user selected attributes. + * It also applies other calculation based on the customer + * @param product + * @param attributes + * @param customer + * @return + * @throws ServiceException + */ + FinalPrice calculateProductPrice(Product product, + List attributes, Customer customer) + throws ServiceException; + + /** + * Method to be used to print a displayable formated amount to the end user + * @param amount + * @param store + * @return + * @throws ServiceException + */ + String getDisplayAmount(BigDecimal amount, MerchantStore store) + throws ServiceException; + + /** + * Method to be used when building an amount formatted with the appropriate currency + * @param amount + * @param locale + * @param currency + * @param store + * @return + * @throws ServiceException + */ + String getDisplayAmount(BigDecimal amount, Locale locale, Currency currency, MerchantStore store) + throws ServiceException; + + /** + * Converts a String amount to BigDecimal + * Takes care of String amount validation + * @param amount + * @return + * @throws ServiceException + */ + BigDecimal getAmount(String amount) throws ServiceException; + + /** + * String format of the money amount without currency symbol + * @param amount + * @param store + * @return + * @throws ServiceException + */ + String getStringAmount(BigDecimal amount, MerchantStore store) + throws ServiceException; + + /** + * Method for calculating sub total + * @param price + * @param quantity + * @return + */ + BigDecimal calculatePriceQuantity(BigDecimal price, int quantity); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/pricing/PricingServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/pricing/PricingServiceImpl.java new file mode 100755 index 0000000000..2ad9e0a782 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/pricing/PricingServiceImpl.java @@ -0,0 +1,123 @@ +package com.salesmanager.core.business.services.catalog.pricing; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.utils.ProductPriceUtils; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.currency.Currency; + +/** + * Contains all the logic required to calculate product price + * @author Carl Samson + * + */ +@Service("pricingService") +public class PricingServiceImpl implements PricingService { + + private static final Logger LOGGER = LoggerFactory.getLogger(PricingServiceImpl.class); + + + @Inject + private ProductPriceUtils priceUtil; + + @Override + public FinalPrice calculateProductPrice(Product product) throws ServiceException { + return priceUtil.getFinalPrice(product); + } + + @Override + public FinalPrice calculateProductPrice(Product product, Customer customer) throws ServiceException { + /** TODO add rules for price calculation **/ + return priceUtil.getFinalPrice(product); + } + + @Override + public FinalPrice calculateProductPrice(Product product, List attributes) throws ServiceException { + return priceUtil.getFinalPrice(product, attributes); + } + + @Override + public FinalPrice calculateProductPrice(Product product, List attributes, Customer customer) throws ServiceException { + /** TODO add rules for price calculation **/ + return priceUtil.getFinalPrice(product, attributes); + } + + @Override + public BigDecimal calculatePriceQuantity(BigDecimal price, int quantity) { + return price.multiply(new BigDecimal(quantity)); + } + + @Override + public String getDisplayAmount(BigDecimal amount, MerchantStore store) throws ServiceException { + try { + return priceUtil.getStoreFormatedAmountWithCurrency(store,amount); + } catch (Exception e) { + LOGGER.error("An error occured when trying to format an amount " + amount.toString()); + throw new ServiceException(e); + } + } + + @Override + public String getDisplayAmount(BigDecimal amount, Locale locale, + Currency currency, MerchantStore store) throws ServiceException { + try { + return priceUtil.getFormatedAmountWithCurrency(locale, currency, amount); + } catch (Exception e) { + LOGGER.error("An error occured when trying to format an amunt " + amount.toString() + " using locale " + locale.toString() + " and currency " + currency.toString()); + throw new ServiceException(e); + } + } + + @Override + public String getStringAmount(BigDecimal amount, MerchantStore store) + throws ServiceException { + try { + return priceUtil.getAdminFormatedAmount(store, amount); + } catch (Exception e) { + LOGGER.error("An error occured when trying to format an amount " + amount.toString()); + throw new ServiceException(e); + } + } + + @Override + public BigDecimal getAmount(String amount) throws ServiceException { + + try { + return priceUtil.getAmount(amount); + } catch (Exception e) { + LOGGER.error("An error occured when trying to format an amount " + amount); + throw new ServiceException(e); + } + + } + + @Override + public FinalPrice calculateProductPrice(ProductAvailability availability) throws ServiceException { + + return priceUtil.getFinalPrice(availability); + } + + @Override + public FinalPrice calculateProductPrice(ProductVariant variant) throws ServiceException { + // TODO Auto-generated method stub + return null; + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/ProductService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/ProductService.java new file mode 100755 index 0000000000..3253ab0ba5 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/ProductService.java @@ -0,0 +1,101 @@ +package com.salesmanager.core.business.services.catalog.product; + +import java.util.List; +import java.util.Locale; +import java.util.Optional; + +import org.springframework.data.domain.Page; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.ProductCriteria; +import com.salesmanager.core.model.catalog.product.ProductList; +import com.salesmanager.core.model.catalog.product.description.ProductDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.tax.taxclass.TaxClass; + + + +public interface ProductService extends SalesManagerEntityService { + + Optional retrieveById(Long id, MerchantStore store); + + void addProductDescription(Product product, ProductDescription description) throws ServiceException; + + ProductDescription getProductDescription(Product product, Language language); + + Product getProductForLocale(long productId, Language language, Locale locale) throws ServiceException; + + List getProductsForLocale(Category category, Language language, Locale locale) throws ServiceException; + + List getProducts(List categoryIds) throws ServiceException; + + List getProductsByIds(List productIds) throws ServiceException; + + /** + * The method to be used + * @param product + * @return + * @throws ServiceException + */ + Product saveProduct(Product product) throws ServiceException; + + /** + * Get a product with only MerchantStore object + * @param productId + * @return + */ + Product getProductWithOnlyMerchantStoreById(Long productId); + + ProductList listByStore(MerchantStore store, Language language, + ProductCriteria criteria); + + boolean exists(String sku, MerchantStore store); + + + /** + * List using Page interface in order to unify all page requests (since 2.16.0) + * @param store + * @param language + * @param criteria + * @param page + * @param count + * @return + */ + Page listByStore(MerchantStore store, Language language, + ProductCriteria criteria, int page, int count); + + List listByStore(MerchantStore store); + + List listByTaxClass(TaxClass taxClass); + + List getProducts(List categoryIds, Language language) + throws ServiceException; + + Product getBySeUrl(MerchantStore store, String seUrl, Locale locale); + + /** + * Product and or product variant + * @param productCode + * @param merchant + * @return + */ + Product getBySku(String productCode, MerchantStore merchant, Language language) throws ServiceException; + + + Product getBySku(String productCode, MerchantStore merchant) throws ServiceException; + + /** + * Find a product for a specific merchant + * @param id + * @param merchant + * @return + */ + Product findOne(Long id, MerchantStore merchant); + + +} + diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/ProductServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/ProductServiceImpl.java new file mode 100755 index 0000000000..883ae072c6 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/ProductServiceImpl.java @@ -0,0 +1,415 @@ +package com.salesmanager.core.business.services.catalog.product; + + +import java.io.InputStream; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.catalog.product.ProductRepository; +import com.salesmanager.core.business.services.catalog.category.CategoryService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductOptionService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductOptionValueService; +import com.salesmanager.core.business.services.catalog.product.availability.ProductAvailabilityService; +import com.salesmanager.core.business.services.catalog.product.image.ProductImageService; +import com.salesmanager.core.business.services.catalog.product.price.ProductPriceService; +import com.salesmanager.core.business.services.catalog.product.relationship.ProductRelationshipService; +import com.salesmanager.core.business.services.catalog.product.review.ProductReviewService; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.business.utils.CatalogServiceHelper; +import com.salesmanager.core.business.utils.CoreConfiguration; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.ProductCriteria; +import com.salesmanager.core.model.catalog.product.ProductList; +import com.salesmanager.core.model.catalog.product.description.ProductDescription; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.catalog.product.relationship.ProductRelationship; +import com.salesmanager.core.model.catalog.product.review.ProductReview; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.ImageContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.tax.taxclass.TaxClass; + +@Service("productService") +public class ProductServiceImpl extends SalesManagerEntityServiceImpl implements ProductService { + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductServiceImpl.class); + + ProductRepository productRepository; + + @Inject + CategoryService categoryService; + + @Inject + ProductAvailabilityService productAvailabilityService; + + @Inject + ProductPriceService productPriceService; + + @Inject + ProductOptionService productOptionService; + + @Inject + ProductOptionValueService productOptionValueService; + + @Inject + ProductAttributeService productAttributeService; + + @Inject + ProductRelationshipService productRelationshipService; + + @Inject + ProductImageService productImageService; + + @Inject + CoreConfiguration configuration; + + @Inject + ProductReviewService productReviewService; + + @Inject + public ProductServiceImpl(ProductRepository productRepository) { + super(productRepository); + this.productRepository = productRepository; + } + + @Override + public Optional retrieveById(Long id, MerchantStore store) { + return Optional.ofNullable(findOne(id,store)); + } + + @Override + public void addProductDescription(Product product, ProductDescription description) throws ServiceException { + + if (product.getDescriptions() == null) { + product.setDescriptions(new HashSet()); + } + + product.getDescriptions().add(description); + description.setProduct(product); + update(product); + + } + + @Override + public List getProducts(List categoryIds) throws ServiceException { + + @SuppressWarnings({ "unchecked", "rawtypes" }) + Set ids = new HashSet(categoryIds); + return productRepository.getProductsListByCategories(ids); + + } + + @Override + public List getProductsByIds(List productIds) throws ServiceException { + Set idSet = productIds.stream().collect(Collectors.toSet()); + return productRepository.getProductsListByIds(idSet); + } + + @Override + public Product getProductWithOnlyMerchantStoreById(Long productId) { + return productRepository.getProductWithOnlyMerchantStoreById(productId); + } + + @Override + public List getProducts(List categoryIds, Language language) throws ServiceException { + + @SuppressWarnings({ "unchecked", "rawtypes" }) + Set ids = new HashSet(categoryIds); + return productRepository.getProductsListByCategories(ids, language); + + } + + @Override + public ProductDescription getProductDescription(Product product, Language language) { + for (ProductDescription description : product.getDescriptions()) { + if (description.getLanguage().equals(language)) { + return description; + } + } + return null; + } + + @Override + public Product getBySeUrl(MerchantStore store, String seUrl, Locale locale) { + return productRepository.getByFriendlyUrl(store, seUrl, locale); + } + + @Override + public Product getProductForLocale(long productId, Language language, Locale locale) throws ServiceException { + Product product = productRepository.getProductForLocale(productId, language, locale); + if (product == null) { + return null; + } + + CatalogServiceHelper.setToAvailability(product, locale); + CatalogServiceHelper.setToLanguage(product, language.getId()); + return product; + } + + @Override + public List getProductsForLocale(Category category, Language language, Locale locale) + throws ServiceException { + + if (category == null) { + throw new ServiceException("The category is null"); + } + + // Get the category list + StringBuilder lineage = new StringBuilder().append(category.getLineage()).append(category.getId()).append("/"); + List categories = categoryService.getListByLineage(category.getMerchantStore(), lineage.toString()); + Set categoryIds = new HashSet(); + for (Category c : categories) { + + categoryIds.add(c.getId()); + + } + + categoryIds.add(category.getId()); + + // Get products + + // Filter availability + + return productRepository.getProductsForLocale(category.getMerchantStore(), categoryIds, language, locale); + } + + @Override + public ProductList listByStore(MerchantStore store, Language language, ProductCriteria criteria) { + + return productRepository.listByStore(store, language, criteria); + } + + @Override + public List listByStore(MerchantStore store) { + + return productRepository.listByStore(store); + } + + @Override + public List listByTaxClass(TaxClass taxClass) { + return productRepository.listByTaxClass(taxClass); + } + + + @Override + public void delete(Product product) throws ServiceException { + Validate.notNull(product, "Product cannot be null"); + Validate.notNull(product.getMerchantStore(), "MerchantStore cannot be null in product"); + product = this.getById(product.getId());// Prevents detached entity + // error + product.setCategories(null); + + Set images = product.getImages(); + + for (ProductImage image : images) { + productImageService.removeProductImage(image); + } + + product.setImages(null); + + // delete reviews + List reviews = productReviewService.getByProductNoCustomers(product); + for (ProductReview review : reviews) { + productReviewService.delete(review); + } + + // related - featured + List relationships = productRelationshipService.listByProduct(product); + for (ProductRelationship relationship : relationships) { + productRelationshipService.deleteRelationship(relationship); + } + + super.delete(product); + //searchService.deleteIndex(product.getMerchantStore(), product); + + } + + @Override + public void create(Product product) throws ServiceException { + saveOrUpdate(product); + } + + @Override + public void update(Product product) throws ServiceException { + saveOrUpdate(product); + } + + + + private Product saveOrUpdate(Product product) throws ServiceException { + Validate.notNull(product, "product cannot be null"); + Validate.notNull(product.getAvailabilities(), "product must have at least one availability"); + Validate.notEmpty(product.getAvailabilities(), "product must have at least one availability"); + + // take care of product images separately + Set originalProductImages = new HashSet(product.getImages()); + + /** save product first **/ + + if (product.getId() != null && product.getId() > 0) { + super.update(product); + } else { + super.create(product); + } + + /** + * Image creation needs extra service to save the file in the CMS + */ + List newImageIds = new ArrayList(); + Set images = product.getImages(); + + try { + + if (images != null && images.size() > 0) { + for (ProductImage image : images) { + if (image.getImage() != null && (image.getId() == null || image.getId() == 0L)) { + image.setProduct(product); + + InputStream inputStream = image.getImage(); + ImageContentFile cmsContentImage = new ImageContentFile(); + cmsContentImage.setFileName(image.getProductImage()); + cmsContentImage.setFile(inputStream); + cmsContentImage.setFileContentType(FileContentType.PRODUCT); + + productImageService.addProductImage(product, image, cmsContentImage); + newImageIds.add(image.getId()); + } else { + if (image.getId() != null) { + productImageService.save(image); + newImageIds.add(image.getId()); + } + } + } + } + + // cleanup old and new images + if (originalProductImages != null) { + for (ProductImage image : originalProductImages) { + + if (image.getImage() != null && image.getId() == null) { + image.setProduct(product); + + InputStream inputStream = image.getImage(); + ImageContentFile cmsContentImage = new ImageContentFile(); + cmsContentImage.setFileName(image.getProductImage()); + cmsContentImage.setFile(inputStream); + cmsContentImage.setFileContentType(FileContentType.PRODUCT); + + productImageService.addProductImage(product, image, cmsContentImage); + newImageIds.add(image.getId()); + } else { + if (!newImageIds.contains(image.getId())) { + productImageService.delete(image); + } + } + } + } + + + + } catch (Exception e) { + LOGGER.error("Cannot save images " + e.getMessage()); + } + + return product; + + } + + @Override + public Product findOne(Long id, MerchantStore merchant) { + Validate.notNull(merchant, "MerchantStore must not be null"); + Validate.notNull(id, "id must not be null"); + return productRepository.getById(id, merchant); + } + + @Override + public Page listByStore(MerchantStore store, Language language, ProductCriteria criteria, int page, + int count) { + + criteria.setPageSize(page); + criteria.setPageSize(count); + criteria.setLegacyPagination(false); + + ProductList productList = productRepository.listByStore(store, language, criteria); + + PageRequest pageRequest = PageRequest.of(page, count); + + @SuppressWarnings({ "rawtypes", "unchecked" }) + Page p = new PageImpl(productList.getProducts(),pageRequest, productList.getTotalCount()); + + return p; + } + + @Override + public Product saveProduct(Product product) throws ServiceException{ + try { + return this.saveOrUpdate(product); + } catch (ServiceException e) { + throw new ServiceException("Cannot create product [" + product.getId() + "]", e); + } + + } + + @Override + public Product getBySku(String productCode, MerchantStore merchant, Language language) throws ServiceException { + + try { + List products = productRepository.findBySku(productCode, merchant.getId()); + if(products.isEmpty()) { + throw new ServiceException("Cannot get product with sku [" + productCode + "]"); + } + BigInteger id = (BigInteger) products.get(0); + return productRepository.getById(id.longValue(), merchant, language); + } catch (Exception e) { + throw new ServiceException("Cannot get product with sku [" + productCode + "]", e); + } + + + + } + + public Product getBySku(String productCode, MerchantStore merchant) throws ServiceException { + + try { + List products = productRepository.findBySku(productCode, merchant.getId()); + if(products.isEmpty()) { + throw new ServiceException("Cannot get product with sku [" + productCode + "]"); + } + BigInteger id = (BigInteger) products.get(0); + return this.findOne(id.longValue(), merchant); + } catch (Exception e) { + throw new ServiceException("Cannot get product with sku [" + productCode + "]", e); + } + + + + } + + @Override + public boolean exists(String sku, MerchantStore store) { + return productRepository.existsBySku(sku, store.getId()); + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductAttributeService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductAttributeService.java new file mode 100755 index 0000000000..bc996d0918 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductAttributeService.java @@ -0,0 +1,36 @@ +package com.salesmanager.core.business.services.catalog.product.attribute; + +import java.util.List; + +import org.springframework.data.domain.Page; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +public interface ProductAttributeService extends + SalesManagerEntityService { + + ProductAttribute saveOrUpdate(ProductAttribute productAttribute) + throws ServiceException; + + List getByOptionId(MerchantStore store, + Long id) throws ServiceException; + + List getByOptionValueId(MerchantStore store, + Long id) throws ServiceException; + + Page getByProductId(MerchantStore store, Product product, Language language, int page, int count) + throws ServiceException; + + Page getByProductId(MerchantStore store, Product product, int page, int count) + throws ServiceException; + + List getByAttributeIds(MerchantStore store, Product product, List ids) + throws ServiceException; + + List getProductAttributesByCategoryLineage(MerchantStore store, String lineage, Language language) throws Exception; +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductAttributeServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductAttributeServiceImpl.java new file mode 100755 index 0000000000..9760b52768 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductAttributeServiceImpl.java @@ -0,0 +1,109 @@ +package com.salesmanager.core.business.services.catalog.product.attribute; + +import java.util.List; + +import javax.inject.Inject; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.catalog.product.attribute.PageableProductAttributeRepository; +import com.salesmanager.core.business.repositories.catalog.product.attribute.ProductAttributeRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +@Service("productAttributeService") +public class ProductAttributeServiceImpl extends SalesManagerEntityServiceImpl + implements ProductAttributeService { + + private ProductAttributeRepository productAttributeRepository; + @Autowired + private PageableProductAttributeRepository pageableProductAttributeRepository; + + @Inject + public ProductAttributeServiceImpl(ProductAttributeRepository productAttributeRepository) { + super(productAttributeRepository); + this.productAttributeRepository = productAttributeRepository; + } + + @Override + public ProductAttribute getById(Long id) { + + return productAttributeRepository.findOne(id); + + } + + @Override + public List getByOptionId(MerchantStore store, Long id) throws ServiceException { + + return productAttributeRepository.findByOptionId(store.getId(), id); + + } + + @Override + public List getByAttributeIds(MerchantStore store, Product product, List ids) + throws ServiceException { + + return productAttributeRepository.findByAttributeIds(store.getId(), product.getId(), ids); + + } + + @Override + public List getByOptionValueId(MerchantStore store, Long id) throws ServiceException { + + return productAttributeRepository.findByOptionValueId(store.getId(), id); + + } + + /** + * Returns all product attributes + */ + @Override + public Page getByProductId(MerchantStore store, Product product, Language language, int page, + int count) throws ServiceException { + + Pageable pageRequest = PageRequest.of(page, count); + return pageableProductAttributeRepository.findByProductId(store.getId(), product.getId(), language.getId(), + pageRequest); + + } + + @Override + public Page getByProductId(MerchantStore store, Product product, int page, int count) + throws ServiceException { + Pageable pageRequest = PageRequest.of(page, count); + return pageableProductAttributeRepository.findByProductId(store.getId(), product.getId(), pageRequest); + + } + + @Override + public ProductAttribute saveOrUpdate(ProductAttribute productAttribute) throws ServiceException { + productAttribute = productAttributeRepository.save(productAttribute); + return productAttribute; + + } + + @Override + public void delete(ProductAttribute attribute) throws ServiceException { + + // override method, this allows the error that we try to remove a detached + // variant + attribute = this.getById(attribute.getId()); + super.delete(attribute); + + } + + @Override + public List getProductAttributesByCategoryLineage(MerchantStore store, String lineage, + Language language) throws Exception { + return productAttributeRepository.findOptionsByCategoryLineage(store.getId(), lineage, language.getId()); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionService.java new file mode 100755 index 0000000000..325890b3d3 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionService.java @@ -0,0 +1,36 @@ +package com.salesmanager.core.business.services.catalog.product.attribute; + +import java.util.List; +import org.springframework.data.domain.Page; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +public interface ProductOptionService extends SalesManagerEntityService { + + List listByStore(MerchantStore store, Language language) + throws ServiceException; + + + List getByName(MerchantStore store, String name, + Language language) throws ServiceException; + + void saveOrUpdate(ProductOption entity) throws ServiceException; + + + List listReadOnly(MerchantStore store, Language language) + throws ServiceException; + + + ProductOption getByCode(MerchantStore store, String optionCode); + + ProductOption getById(MerchantStore store, Long optionId); + + Page getByMerchant(MerchantStore store, Language language, String name, int page, int count); + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionServiceImpl.java new file mode 100755 index 0000000000..1962254088 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionServiceImpl.java @@ -0,0 +1,125 @@ +package com.salesmanager.core.business.services.catalog.product.attribute; + +import java.util.List; +import javax.inject.Inject; +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.catalog.product.attribute.PageableProductOptionRepository; +import com.salesmanager.core.business.repositories.catalog.product.attribute.ProductOptionRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +@Service("productOptionService") +public class ProductOptionServiceImpl extends + SalesManagerEntityServiceImpl implements ProductOptionService { + + + private ProductOptionRepository productOptionRepository; + + @Autowired + private PageableProductOptionRepository pageableProductOptionRepository; + + @Inject + private ProductAttributeService productAttributeService; + + @Inject + public ProductOptionServiceImpl( + ProductOptionRepository productOptionRepository) { + super(productOptionRepository); + this.productOptionRepository = productOptionRepository; + } + + @Override + public List listByStore(MerchantStore store, Language language) throws ServiceException { + + + return productOptionRepository.findByStoreId(store.getId(), language.getId()); + + + } + + @Override + public List listReadOnly(MerchantStore store, Language language) throws ServiceException { + + return productOptionRepository.findByReadOnly(store.getId(), language.getId(), true); + + + } + + + + @Override + public List getByName(MerchantStore store, String name, Language language) throws ServiceException { + + try { + return productOptionRepository.findByName(store.getId(), name, language.getId()); + } catch (Exception e) { + throw new ServiceException(e); + } + + + } + + @Override + public void saveOrUpdate(ProductOption entity) throws ServiceException { + + + //save or update (persist and attach entities + if(entity.getId()!=null && entity.getId()>0) { + super.update(entity); + } else { + super.save(entity); + } + + } + + @Override + public void delete(ProductOption entity) throws ServiceException { + + //remove all attributes having this option + List attributes = productAttributeService.getByOptionId(entity.getMerchantStore(), entity.getId()); + + for(ProductAttribute attribute : attributes) { + productAttributeService.delete(attribute); + } + + ProductOption option = this.getById(entity.getId()); + + //remove option + super.delete(option); + + } + + @Override + public ProductOption getByCode(MerchantStore store, String optionCode) { + return productOptionRepository.findByCode(store.getId(), optionCode); + } + + @Override + public ProductOption getById(MerchantStore store, Long optionId) { + return productOptionRepository.findOne(store.getId(), optionId); + } + + @Override + public Page getByMerchant(MerchantStore store, Language language, String name, + int page, int count) { + Validate.notNull(store, "MerchantStore cannot be null"); + Pageable p = PageRequest.of(page, count); + return pageableProductOptionRepository.listOptions(store.getId(), name, p); + } + + + + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionSetService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionSetService.java new file mode 100644 index 0000000000..84a5326c90 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionSetService.java @@ -0,0 +1,22 @@ +package com.salesmanager.core.business.services.catalog.product.attribute; + +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionSet; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +public interface ProductOptionSetService extends SalesManagerEntityService { + + List listByStore(MerchantStore store, Language language) + throws ServiceException; + + + ProductOptionSet getById(MerchantStore store, Long optionId, Language lang); + ProductOptionSet getCode(MerchantStore store, String code); + List getByProductType (Long productTypeId, MerchantStore store, Language lang); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionSetServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionSetServiceImpl.java new file mode 100644 index 0000000000..b50ce34c5b --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionSetServiceImpl.java @@ -0,0 +1,57 @@ +package com.salesmanager.core.business.services.catalog.product.attribute; + +import java.util.List; + +import javax.inject.Inject; + +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.catalog.product.attribute.ProductOptionSetRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionSet; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +@Service("productOptionSetService") +public class ProductOptionSetServiceImpl extends + SalesManagerEntityServiceImpl implements ProductOptionSetService { + + + private ProductOptionSetRepository productOptionSetRepository; + + + @Inject + public ProductOptionSetServiceImpl( + ProductOptionSetRepository productOptionSetRepository) { + super(productOptionSetRepository); + this.productOptionSetRepository = productOptionSetRepository; + } + + + @Override + public List listByStore(MerchantStore store, Language language) throws ServiceException { + return productOptionSetRepository.findByStore(store.getId(), language.getId()); + } + + + @Override + public ProductOptionSet getById(MerchantStore store, Long optionSetId, Language lang) { + return productOptionSetRepository.findOne(store.getId(), optionSetId, lang.getId()); + } + + + @Override + public ProductOptionSet getCode(MerchantStore store, String code) { + return productOptionSetRepository.findByCode(store.getId(), code); + } + + + @Override + public List getByProductType(Long productTypeId, MerchantStore store, Language lang) { + return productOptionSetRepository.findByProductType(productTypeId, store.getId(), lang.getId()); + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionValueService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionValueService.java new file mode 100755 index 0000000000..53a0d8e5c8 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionValueService.java @@ -0,0 +1,34 @@ +package com.salesmanager.core.business.services.catalog.product.attribute; + +import java.util.List; + +import org.springframework.data.domain.Page; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +public interface ProductOptionValueService extends SalesManagerEntityService { + + void saveOrUpdate(ProductOptionValue entity) throws ServiceException; + + List getByName(MerchantStore store, String name, + Language language) throws ServiceException; + + + List listByStore(MerchantStore store, Language language) + throws ServiceException; + + List listByStoreNoReadOnly(MerchantStore store, + Language language) throws ServiceException; + + ProductOptionValue getByCode(MerchantStore store, String optionValueCode); + + ProductOptionValue getById(MerchantStore store, Long optionValueId); + + Page getByMerchant(MerchantStore store, Language language, String name, int page, int count); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionValueServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionValueServiceImpl.java new file mode 100755 index 0000000000..d49eddf96e --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/attribute/ProductOptionValueServiceImpl.java @@ -0,0 +1,124 @@ +package com.salesmanager.core.business.services.catalog.product.attribute; + +import java.util.List; + +import javax.inject.Inject; + +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.catalog.product.attribute.PageableProductOptionValueRepository; +import com.salesmanager.core.business.repositories.catalog.product.attribute.ProductOptionValueRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +@Service("productOptionValueService") +public class ProductOptionValueServiceImpl extends + SalesManagerEntityServiceImpl implements + ProductOptionValueService { + + @Inject + private ProductAttributeService productAttributeService; + + @Autowired + private PageableProductOptionValueRepository pageableProductOptionValueRepository; + + private ProductOptionValueRepository productOptionValueRepository; + + @Inject + public ProductOptionValueServiceImpl( + ProductOptionValueRepository productOptionValueRepository) { + super(productOptionValueRepository); + this.productOptionValueRepository = productOptionValueRepository; + } + + + @Override + public List listByStore(MerchantStore store, Language language) throws ServiceException { + + return productOptionValueRepository.findByStoreId(store.getId(), language.getId()); + } + + @Override + public List listByStoreNoReadOnly(MerchantStore store, Language language) throws ServiceException { + + return productOptionValueRepository.findByReadOnly(store.getId(), language.getId(), false); + } + + @Override + public List getByName(MerchantStore store, String name, Language language) throws ServiceException { + + try { + return productOptionValueRepository.findByName(store.getId(), name, language.getId()); + } catch (Exception e) { + throw new ServiceException(e); + } + + + } + + @Override + public void saveOrUpdate(ProductOptionValue entity) throws ServiceException { + + + //save or update (persist and attach entities + if(entity.getId()!=null && entity.getId()>0) { + + super.update(entity); + + } else { + + super.save(entity); + + } + + } + + + public void delete(ProductOptionValue entity) throws ServiceException { + + //remove all attributes having this option + List attributes = productAttributeService.getByOptionValueId(entity.getMerchantStore(), entity.getId()); + + for(ProductAttribute attribute : attributes) { + productAttributeService.delete(attribute); + } + + ProductOptionValue option = getById(entity.getId()); + + //remove option + super.delete(option); + + } + + @Override + public ProductOptionValue getByCode(MerchantStore store, String optionValueCode) { + return productOptionValueRepository.findByCode(store.getId(), optionValueCode); + } + + + @Override + public ProductOptionValue getById(MerchantStore store, Long optionValueId) { + return productOptionValueRepository.findOne(store.getId(), optionValueId); + } + + + @Override + public Page getByMerchant(MerchantStore store, Language language, String name, int page, + int count) { + Validate.notNull(store, "MerchantStore cannot be null"); + Pageable p = PageRequest.of(page, count); + return pageableProductOptionValueRepository.listOptionValues(store.getId(), name, p); + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/availability/ProductAvailabilityService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/availability/ProductAvailabilityService.java new file mode 100755 index 0000000000..1d6a9233dc --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/availability/ProductAvailabilityService.java @@ -0,0 +1,47 @@ +package com.salesmanager.core.business.services.catalog.product.availability; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.domain.Page; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.merchant.MerchantStore; + +public interface ProductAvailabilityService extends + SalesManagerEntityService { + + ProductAvailability saveOrUpdate(ProductAvailability availability) throws ServiceException; + + Page listByProduct(Long productId, MerchantStore store, int page, int count); + + /** + * Get by product sku and store + * @param sku + * @param store + * @return + */ + Page getBySku(String sku, MerchantStore store, int page, int count); + + + /** + * Get by sku + * @param sku + * @return + */ + Page getBySku(String sku, int page, int count); + + /** + * All availability by product / product variant sku and store + * @param sku + * @param store + * @return + */ + List getBySku(String sku, MerchantStore store); + + Optional getById(Long availabilityId, MerchantStore store); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/availability/ProductAvailabilityServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/availability/ProductAvailabilityServiceImpl.java new file mode 100755 index 0000000000..1bfc7fe28d --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/availability/ProductAvailabilityServiceImpl.java @@ -0,0 +1,98 @@ +package com.salesmanager.core.business.services.catalog.product.availability; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import javax.inject.Inject; + +import org.apache.commons.lang3.Validate; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.catalog.product.availability.PageableProductAvailabilityRepository; +import com.salesmanager.core.business.repositories.catalog.product.availability.ProductAvailabilityRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.merchant.MerchantStore; + +/** + * Availability -> Inventory + * + * @author carlsamson + * + */ + +@Service("productAvailabilityService") +public class ProductAvailabilityServiceImpl extends SalesManagerEntityServiceImpl + implements ProductAvailabilityService { + + private ProductAvailabilityRepository productAvailabilityRepository; + + @Inject + private PageableProductAvailabilityRepository pageableProductAvailabilityRepository; + + @Inject + public ProductAvailabilityServiceImpl(ProductAvailabilityRepository productAvailabilityRepository) { + super(productAvailabilityRepository); + this.productAvailabilityRepository = productAvailabilityRepository; + } + + @Override + public ProductAvailability saveOrUpdate(ProductAvailability availability) throws ServiceException { + if (isPositive(availability.getId())) { + update(availability); + } else { + create(availability); + } + + return availability; + } + + private boolean isPositive(Long id) { + return Objects.nonNull(id) && id > 0; + } + + + + @Override + public Page listByProduct(Long productId, MerchantStore store, int page, + int count) { + Validate.notNull(productId, "Product cannot be null"); + Validate.notNull(store, "MercantStore cannot be null"); + Pageable pageRequest = PageRequest.of(page, count); + return pageableProductAvailabilityRepository.getByProductId(productId, store.getCode(), pageRequest); + } + + + + @Override + public Optional getById(Long availabilityId, MerchantStore store) { + Validate.notNull(store, "Merchant must not be null"); + return Optional.ofNullable(productAvailabilityRepository.getById(availabilityId)); + } + + @Override + public Page getBySku(String sku, MerchantStore store, int page, int count) { + Validate.notNull(store, "MerchantStore cannot be null"); + Pageable pageRequest = PageRequest.of(page, count); + return pageableProductAvailabilityRepository.getBySku(sku, store.getCode(), pageRequest); + } + + @Override + public Page getBySku(String sku, int page, int count) { + Pageable pageRequest = PageRequest.of(page, count); + return pageableProductAvailabilityRepository.getBySku(sku, pageRequest); + } + + @Override + public List getBySku(String sku, MerchantStore store) { + Validate.notNull(store, "MerchantStore cannot be null"); + return productAvailabilityRepository.getBySku(sku, store.getCode()); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/file/DigitalProductService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/file/DigitalProductService.java new file mode 100755 index 0000000000..0cf33b4b9b --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/file/DigitalProductService.java @@ -0,0 +1,24 @@ +package com.salesmanager.core.business.services.catalog.product.file; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.file.DigitalProduct; +import com.salesmanager.core.model.content.InputContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; + + +public interface DigitalProductService extends SalesManagerEntityService { + + void saveOrUpdate(DigitalProduct digitalProduct) throws ServiceException; + + void addProductFile(Product product, DigitalProduct digitalProduct, + InputContentFile inputFile) throws ServiceException; + + + + DigitalProduct getByProduct(MerchantStore store, Product product) + throws ServiceException; + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/file/DigitalProductServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/file/DigitalProductServiceImpl.java new file mode 100755 index 0000000000..c3d9e1ec40 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/file/DigitalProductServiceImpl.java @@ -0,0 +1,117 @@ +package com.salesmanager.core.business.services.catalog.product.file; + +import java.util.Optional; + +import javax.inject.Inject; +import org.springframework.stereotype.Service; +import org.springframework.util.Assert; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.cms.content.StaticContentFileManager; +import com.salesmanager.core.business.repositories.catalog.product.file.DigitalProductRepository; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.file.DigitalProduct; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.InputContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; + +@Service("digitalProductService") +public class DigitalProductServiceImpl extends SalesManagerEntityServiceImpl + implements DigitalProductService { + + + private DigitalProductRepository digitalProductRepository; + + @Inject + StaticContentFileManager productDownloadsFileManager; + + @Inject + ProductService productService; + + @Inject + public DigitalProductServiceImpl(DigitalProductRepository digitalProductRepository) { + super(digitalProductRepository); + this.digitalProductRepository = digitalProductRepository; + } + + @Override + public void addProductFile(Product product, DigitalProduct digitalProduct, InputContentFile inputFile) throws ServiceException { + + Assert.notNull(digitalProduct,"DigitalProduct cannot be null"); + Assert.notNull(product,"Product cannot be null"); + digitalProduct.setProduct(product); + + try { + + Assert.notNull(inputFile.getFile(),"InputContentFile.file cannot be null"); + + Assert.notNull(product.getMerchantStore(),"Product.merchantStore cannot be null"); + this.saveOrUpdate(digitalProduct); + + String path = null; + + + productDownloadsFileManager.addFile(product.getMerchantStore().getCode(), Optional.of(path), inputFile); + + product.setProductVirtual(true); + productService.update(product); + + } catch (Exception e) { + throw new ServiceException(e); + } finally { + try { + + if(inputFile.getFile()!=null) { + inputFile.getFile().close(); + } + + } catch(Exception ignore) {} + } + + + } + + @Override + public DigitalProduct getByProduct(MerchantStore store, Product product) throws ServiceException { + return digitalProductRepository.findByProduct(store.getId(), product.getId()); + } + + @Override + public void delete(DigitalProduct digitalProduct) throws ServiceException { + + Assert.notNull(digitalProduct,"DigitalProduct cannot be null"); + Assert.notNull(digitalProduct.getProduct(),"DigitalProduct.product cannot be null"); + //refresh file + digitalProduct = this.getById(digitalProduct.getId()); + super.delete(digitalProduct); + + String path = null; + + productDownloadsFileManager.removeFile(digitalProduct.getProduct().getMerchantStore().getCode(), FileContentType.PRODUCT, digitalProduct.getProductFileName(), Optional.of(path)); + digitalProduct.getProduct().setProductVirtual(false); + productService.update(digitalProduct.getProduct()); + } + + + @Override + public void saveOrUpdate(DigitalProduct digitalProduct) throws ServiceException { + + Assert.notNull(digitalProduct,"DigitalProduct cannot be null"); + Assert.notNull(digitalProduct.getProduct(),"DigitalProduct.product cannot be null"); + if(digitalProduct.getId()==null || digitalProduct.getId() ==0) { + super.save(digitalProduct); + } else { + super.create(digitalProduct); + } + + digitalProduct.getProduct().setProductVirtual(true); + productService.update(digitalProduct.getProduct()); + + + } + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/image/ProductImageService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/image/ProductImageService.java new file mode 100755 index 0000000000..0d43cdc039 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/image/ProductImageService.java @@ -0,0 +1,79 @@ +package com.salesmanager.core.business.services.catalog.product.image; + +import java.util.List; +import java.util.Optional; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.file.ProductImageSize; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.content.ImageContentFile; +import com.salesmanager.core.model.content.OutputContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; + + +public interface ProductImageService extends SalesManagerEntityService { + + + + /** + * Add a ProductImage to the persistence and an entry to the CMS + * @param product + * @param productImage + * @param file + * @throws ServiceException + */ + void addProductImage(Product product, ProductImage productImage, ImageContentFile inputImage) + throws ServiceException; + + /** + * Get the image ByteArrayOutputStream and content description from CMS + * @param productImage + * @return + * @throws ServiceException + */ + OutputContentFile getProductImage(ProductImage productImage, ProductImageSize size) + throws ServiceException; + + /** + * Returns all Images for a given product + * @param product + * @return + * @throws ServiceException + */ + List getProductImages(Product product) + throws ServiceException; + + /** + * Get a product image by name for a given product id + * @param imageName + * @param productId + * @param store + * @return + */ + Optional getProductImage(Long imageId, Long productId, MerchantStore store); + + void removeProductImage(ProductImage productImage) throws ServiceException; + + ProductImage saveOrUpdate(ProductImage productImage) throws ServiceException; + + /** + * Returns an image file from required identifier. This method is + * used by the image servlet + * @param store + * @param product + * @param fileName + * @param size + * @return + * @throws ServiceException + */ + OutputContentFile getProductImage(String storeCode, String productCode, + String fileName, final ProductImageSize size) throws ServiceException; + + void addProductImages(Product product, List productImages) + throws ServiceException; + + void updateProductImage(Product product, ProductImage productImage); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/image/ProductImageServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/image/ProductImageServiceImpl.java new file mode 100755 index 0000000000..7e55d99437 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/image/ProductImageServiceImpl.java @@ -0,0 +1,206 @@ +package com.salesmanager.core.business.services.catalog.product.image; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; +import org.springframework.util.Assert; + +import com.salesmanager.core.business.configuration.events.products.DeleteProductImageEvent; +import com.salesmanager.core.business.configuration.events.products.SaveProductImageEvent; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.cms.product.ProductFileManager; +import com.salesmanager.core.business.repositories.catalog.product.image.ProductImageRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.file.ProductImageSize; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.catalog.product.image.ProductImageDescription; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.ImageContentFile; +import com.salesmanager.core.model.content.OutputContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; + +@Service("productImage") +public class ProductImageServiceImpl extends SalesManagerEntityServiceImpl + implements ProductImageService { + + private ProductImageRepository productImageRepository; + + @Inject + public ProductImageServiceImpl(ProductImageRepository productImageRepository) { + super(productImageRepository); + this.productImageRepository = productImageRepository; + } + + @Inject + private ProductFileManager productFileManager; + + @Autowired + private ApplicationEventPublisher eventPublisher; + + public ProductImage getById(Long id) { + + return productImageRepository.findOne(id); + } + + @Override + public void addProductImages(Product product, List productImages) throws ServiceException { + + try { + for (ProductImage productImage : productImages) { + + Assert.notNull(productImage.getImage()); + + InputStream inputStream = productImage.getImage(); + ImageContentFile cmsContentImage = new ImageContentFile(); + cmsContentImage.setFileName(productImage.getProductImage()); + cmsContentImage.setFile(inputStream); + cmsContentImage.setFileContentType(FileContentType.PRODUCT); + + addProductImage(product, productImage, cmsContentImage); + } + + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + @Override + public void addProductImage(Product product, ProductImage productImage, ImageContentFile inputImage) + throws ServiceException { + + productImage.setProduct(product); + + try { + if (productImage.getImageType() == 0) { + Assert.notNull(inputImage.getFile(), "ImageContentFile.file cannot be null"); + productFileManager.addProductImage(productImage, inputImage); + } + + // insert ProductImage + ProductImage img = saveOrUpdate(productImage); + //manual workaround since aspect is not working + eventPublisher.publishEvent(new SaveProductImageEvent(eventPublisher, img, product)); + + } catch (Exception e) { + throw new ServiceException(e); + } finally { + try { + + if (inputImage.getFile() != null) { + inputImage.getFile().close(); + } + + } catch (Exception ignore) { + + } + } + + } + + @Override + public ProductImage saveOrUpdate(ProductImage productImage) throws ServiceException { + + return productImageRepository.save(productImage); + + } + + public void addProductImageDescription(ProductImage productImage, ProductImageDescription description) + throws ServiceException { + + if (productImage.getDescriptions() == null) { + productImage.setDescriptions(new ArrayList()); + } + + productImage.getDescriptions().add(description); + description.setProductImage(productImage); + update(productImage); + + } + + // TODO get default product image + + @Override + public OutputContentFile getProductImage(ProductImage productImage, ProductImageSize size) throws ServiceException { + + ProductImage pi = new ProductImage(); + String imageName = productImage.getProductImage(); + if (size == ProductImageSize.LARGE) { + imageName = "L-" + imageName; + } + + if (size == ProductImageSize.SMALL) { + imageName = "S-" + imageName; + } + + pi.setProductImage(imageName); + pi.setProduct(productImage.getProduct()); + + return productFileManager.getProductImage(pi); + + } + + @Override + public OutputContentFile getProductImage(final String storeCode, final String productCode, final String fileName, + final ProductImageSize size) throws ServiceException { + return productFileManager.getProductImage(storeCode, productCode, fileName, size); + + } + + @Override + public List getProductImages(Product product) throws ServiceException { + return productFileManager.getImages(product); + } + + @Override + public void removeProductImage(ProductImage productImage) throws ServiceException { + + if (!StringUtils.isBlank(productImage.getProductImage())) { + productFileManager.removeProductImage(productImage);// managed internally + } + ProductImage p = getById(productImage.getId()); + + Product product = p.getProduct(); + + + delete(p); + /** + * workaround for aspect + */ + eventPublisher.publishEvent(new DeleteProductImageEvent(eventPublisher, p, product)); + + + } + + @Override + public Optional getProductImage(Long imageId, Long productId, MerchantStore store) { + + Optional image = Optional.empty(); + + ProductImage img = productImageRepository.finById(imageId, productId, store.getCode()); + if (img != null) { + image = Optional.of(img); + } + + return image; + } + + @Override + public void updateProductImage(Product product, ProductImage productImage) { + Validate.notNull(product, "Product cannot be null"); + Validate.notNull(productImage, "ProductImage cannot be null"); + productImage.setProduct(product); + productImageRepository.save(productImage); + + } +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/manufacturer/ManufacturerService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/manufacturer/ManufacturerService.java new file mode 100755 index 0000000000..65a70e7839 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/manufacturer/ManufacturerService.java @@ -0,0 +1,62 @@ +package com.salesmanager.core.business.services.catalog.product.manufacturer; + +import java.util.List; +import org.springframework.data.domain.Page; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.catalog.product.manufacturer.ManufacturerDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +public interface ManufacturerService extends SalesManagerEntityService { + + List listByStore(MerchantStore store, Language language) + throws ServiceException; + + List listByStore(MerchantStore store) throws ServiceException; + + Page listByStore(MerchantStore store, Language language, int page, int count) throws ServiceException; + + Page listByStore(MerchantStore store, Language language, String name, int page, int count) throws ServiceException; + + void saveOrUpdate(Manufacturer manufacturer) throws ServiceException; + + void addManufacturerDescription(Manufacturer manufacturer, ManufacturerDescription description) throws ServiceException; + + Long getCountManufAttachedProducts( Manufacturer manufacturer ) throws ServiceException; + + void delete(Manufacturer manufacturer) throws ServiceException; + + Manufacturer getByCode(MerchantStore store, String code); + + /** + * List manufacturers by products from a given list of categories + * @param store + * @param ids + * @param language + * @return + * @throws ServiceException + */ + List listByProductsByCategoriesId(MerchantStore store, + List ids, Language language) throws ServiceException; + + /** + * List by product in category lineage + * @param store + * @param category + * @param language + * @return + * @throws ServiceException + */ + List listByProductsInCategory(MerchantStore store, + Category category, Language language) throws ServiceException; + + Page listByStore(MerchantStore store, String name, + int page, int count) throws ServiceException; + + int count(MerchantStore store); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/manufacturer/ManufacturerServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/manufacturer/ManufacturerServiceImpl.java new file mode 100755 index 0000000000..03cb476802 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/manufacturer/ManufacturerServiceImpl.java @@ -0,0 +1,151 @@ +package com.salesmanager.core.business.services.catalog.product.manufacturer; + + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.catalog.product.manufacturer.ManufacturerRepository; +import com.salesmanager.core.business.repositories.catalog.product.manufacturer.PageableManufacturerRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.catalog.product.manufacturer.ManufacturerDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import org.jsoup.helper.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import javax.inject.Inject; +import java.util.HashSet; +import java.util.List; + + + +@Service("manufacturerService") +public class ManufacturerServiceImpl extends SalesManagerEntityServiceImpl + implements ManufacturerService { + + private static final Logger LOGGER = LoggerFactory.getLogger(ManufacturerServiceImpl.class); + + @Inject + private PageableManufacturerRepository pageableManufacturerRepository; + + private ManufacturerRepository manufacturerRepository; + + @Inject + public ManufacturerServiceImpl(ManufacturerRepository manufacturerRepository) { + super(manufacturerRepository); + this.manufacturerRepository = manufacturerRepository; + } + + @Override + public void delete(Manufacturer manufacturer) throws ServiceException { + manufacturer = this.getById(manufacturer.getId()); + super.delete(manufacturer); + } + + @Override + public Long getCountManufAttachedProducts(Manufacturer manufacturer) throws ServiceException { + return manufacturerRepository.countByProduct(manufacturer.getId()); + // .getCountManufAttachedProducts( manufacturer ); + } + + + @Override + public List listByStore(MerchantStore store, Language language) + throws ServiceException { + return manufacturerRepository.findByStoreAndLanguage(store.getId(), language.getId()); + } + + @Override + public List listByStore(MerchantStore store) throws ServiceException { + return manufacturerRepository.findByStore(store.getId()); + } + + @Override + public List listByProductsByCategoriesId(MerchantStore store, List ids, + Language language) throws ServiceException { + return manufacturerRepository.findByCategoriesAndLanguage(ids, language.getId()); + } + + @Override + public void addManufacturerDescription(Manufacturer manufacturer, + ManufacturerDescription description) throws ServiceException { + + + if (manufacturer.getDescriptions() == null) { + manufacturer.setDescriptions(new HashSet()); + } + + manufacturer.getDescriptions().add(description); + description.setManufacturer(manufacturer); + update(manufacturer); + } + + @Override + public void saveOrUpdate(Manufacturer manufacturer) throws ServiceException { + + LOGGER.debug("Creating Manufacturer"); + + if (manufacturer.getId() != null && manufacturer.getId() > 0) { + super.update(manufacturer); + + } else { + super.create(manufacturer); + + } + } + + @Override + public Manufacturer getByCode(com.salesmanager.core.model.merchant.MerchantStore store, + String code) { + return manufacturerRepository.findByCodeAndMerchandStore(code, store.getId()); + } + + @Override + public Manufacturer getById(Long id) { + return manufacturerRepository.findOne(id); + } + + @Override + public List listByProductsInCategory(MerchantStore store, Category category, + Language language) throws ServiceException { + Validate.notNull(store, "Store cannot be null"); + Validate.notNull(category,"Category cannot be null"); + Validate.notNull(language, "Language cannot be null"); + return manufacturerRepository.findByProductInCategoryId(store.getId(), category.getLineage(), language.getId()); + } + + @Override + public Page listByStore(MerchantStore store, Language language, int page, int count) + throws ServiceException { + + Pageable pageRequest = PageRequest.of(page, count); + return pageableManufacturerRepository.findByStore(store.getId(), language.getId(), null, pageRequest); + } + + @Override + public int count(MerchantStore store) { + Validate.notNull(store, "Merchant must not be null"); + return manufacturerRepository.count(store.getId()); + } + + @Override + public Page listByStore(MerchantStore store, Language language, String name, + int page, int count) throws ServiceException { + + Pageable pageRequest = PageRequest.of(page, count); + return pageableManufacturerRepository.findByStore(store.getId(), language.getId(), name, pageRequest); + } + + @Override + public Page listByStore(MerchantStore store, String name, int page, int count) + throws ServiceException { + + Pageable pageRequest = PageRequest.of(page, count); + return pageableManufacturerRepository.findByStore(store.getId(), name, pageRequest); + } +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/price/ProductPriceService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/price/ProductPriceService.java new file mode 100755 index 0000000000..098c82c9a2 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/price/ProductPriceService.java @@ -0,0 +1,24 @@ +package com.salesmanager.core.business.services.catalog.product.price; + +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPriceDescription; +import com.salesmanager.core.model.merchant.MerchantStore; + +public interface ProductPriceService extends SalesManagerEntityService { + + void addDescription(ProductPrice price, ProductPriceDescription description) throws ServiceException; + + ProductPrice saveOrUpdate(ProductPrice price) throws ServiceException; + + List findByProductSku(String sku, MerchantStore store); + + ProductPrice findById(Long priceId, String sku, MerchantStore store); + + List findByInventoryId(Long productInventoryId, String sku, MerchantStore store); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/price/ProductPriceServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/price/ProductPriceServiceImpl.java new file mode 100755 index 0000000000..4a62846c69 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/price/ProductPriceServiceImpl.java @@ -0,0 +1,78 @@ +package com.salesmanager.core.business.services.catalog.product.price; + + + +import java.util.List; + +import javax.inject.Inject; + +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.catalog.product.price.ProductPriceRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPriceDescription; +import com.salesmanager.core.model.merchant.MerchantStore; + +@Service("productPrice") +public class ProductPriceServiceImpl extends SalesManagerEntityServiceImpl + implements ProductPriceService { + + private ProductPriceRepository productPriceRepository; + + @Inject + public ProductPriceServiceImpl(ProductPriceRepository productPriceRepository) { + super(productPriceRepository); + this.productPriceRepository = productPriceRepository; + } + + @Override + public void addDescription(ProductPrice price, + ProductPriceDescription description) throws ServiceException { + price.getDescriptions().add(description); + update(price); + } + + + @Override + public ProductPrice saveOrUpdate(ProductPrice price) throws ServiceException { + + + ProductPrice returnEntity = productPriceRepository.save(price); + + return returnEntity; + + + } + + @Override + public void delete(ProductPrice price) throws ServiceException { + + //override method, this allows the error that we try to remove a detached variant + price = this.getById(price.getId()); + super.delete(price); + + } + + @Override + public List findByProductSku(String sku, MerchantStore store) { + + return productPriceRepository.findByProduct(sku, store.getCode()); + } + + @Override + public ProductPrice findById(Long priceId, String sku, MerchantStore store) { + + return productPriceRepository.findByProduct(sku, priceId, store.getCode()); + } + + @Override + public List findByInventoryId(Long productInventoryId, String sku, MerchantStore store) { + + return productPriceRepository.findByProductInventoty(sku, productInventoryId, store.getCode()); + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/relationship/ProductRelationshipService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/relationship/ProductRelationshipService.java new file mode 100755 index 0000000000..0bf4e0a2e0 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/relationship/ProductRelationshipService.java @@ -0,0 +1,110 @@ +package com.salesmanager.core.business.services.catalog.product.relationship; + +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.relationship.ProductRelationship; +import com.salesmanager.core.model.catalog.product.relationship.ProductRelationshipType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +public interface ProductRelationshipService extends + SalesManagerEntityService { + + void saveOrUpdate(ProductRelationship relationship) throws ServiceException; + + /** + * Get product relationship List for a given type (RELATED, FEATURED...) and language allows + * to return the product description in the appropriate language + * @param store + * @param product + * @param type + * @param language + * @return + * @throws ServiceException + */ + List getByType(MerchantStore store, Product product, + ProductRelationshipType type, Language language) throws ServiceException; + + /** + * Find by product and group name + * @param store + * @param product + * @param name + * @return + * @throws ServiceException + */ + List getByType(MerchantStore store, Product product, + String name) throws ServiceException; + + /** + * Get product relationship List for a given type (RELATED, FEATURED...) and a given base product + * @param store + * @param product + * @param type + * @return + * @throws ServiceException + */ + List getByType(MerchantStore store, Product product, + ProductRelationshipType type) + throws ServiceException; + + /** + * Get product relationship List for a given type (RELATED, FEATURED...) + * @param store + * @param type + * @return + * @throws ServiceException + */ + List getByType(MerchantStore store, + ProductRelationshipType type) throws ServiceException; + + List listByProduct(Product product) + throws ServiceException; + + List getByType(MerchantStore store, + ProductRelationshipType type, Language language) + throws ServiceException; + + /** + * Get a list of relationship acting as groups of products + * @param store + * @return + */ + List getGroups(MerchantStore store); + + /** + * Get group by store and group name (code) + * @param store + * @param name + * @return + */ + List getGroupDefinition(MerchantStore store, String name); + + /** + * Creates a product group + * @param groupName + * @throws ServiceException + */ + void addGroup(MerchantStore store, String groupName) throws ServiceException; + + List getByGroup(MerchantStore store, String groupName) + throws ServiceException; + + void deleteGroup(MerchantStore store, String groupName) + throws ServiceException; + + void deactivateGroup(MerchantStore store, String groupName) + throws ServiceException; + + void deleteRelationship(ProductRelationship relationship) throws ServiceException; + + void activateGroup(MerchantStore store, String groupName) + throws ServiceException; + + List getByGroup(MerchantStore store, String groupName, + Language language) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/relationship/ProductRelationshipServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/relationship/ProductRelationshipServiceImpl.java new file mode 100755 index 0000000000..6c72269e14 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/relationship/ProductRelationshipServiceImpl.java @@ -0,0 +1,162 @@ +package com.salesmanager.core.business.services.catalog.product.relationship; + +import java.util.List; + +import javax.inject.Inject; + +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.catalog.product.relationship.ProductRelationshipRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.relationship.ProductRelationship; +import com.salesmanager.core.model.catalog.product.relationship.ProductRelationshipType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +@Service("productRelationshipService") +public class ProductRelationshipServiceImpl extends + SalesManagerEntityServiceImpl implements + ProductRelationshipService { + + + private ProductRelationshipRepository productRelationshipRepository; + + @Inject + public ProductRelationshipServiceImpl( + ProductRelationshipRepository productRelationshipRepository) { + super(productRelationshipRepository); + this.productRelationshipRepository = productRelationshipRepository; + } + + @Override + public void saveOrUpdate(ProductRelationship relationship) throws ServiceException { + + if(relationship.getId()!=null && relationship.getId()>0) { + + this.update(relationship); + + } else { + this.create(relationship); + } + + } + + + @Override + public void addGroup(MerchantStore store, String groupName) throws ServiceException { + ProductRelationship relationship = new ProductRelationship(); + relationship.setCode(groupName); + relationship.setStore(store); + relationship.setActive(true); + this.save(relationship); + } + + @Override + public List getGroups(MerchantStore store) { + return productRelationshipRepository.getGroups(store); + } + + @Override + public void deleteGroup(MerchantStore store, String groupName) throws ServiceException { + List entities = productRelationshipRepository.getByGroup(store, groupName); + for(ProductRelationship relation : entities) { + this.delete(relation); + } + } + + @Override + public void deactivateGroup(MerchantStore store, String groupName) throws ServiceException { + List entities = getGroupDefinition(store, groupName); + for(ProductRelationship relation : entities) { + relation.setActive(false); + this.saveOrUpdate(relation); + } + } + + @Override + public void activateGroup(MerchantStore store, String groupName) throws ServiceException { + List entities = getGroupDefinition(store, groupName); + for(ProductRelationship relation : entities) { + relation.setActive(true); + this.saveOrUpdate(relation); + } + } + + public void deleteRelationship(ProductRelationship relationship) throws ServiceException { + + //throws detached exception so need to query first + relationship = this.getById(relationship.getId()); + if(relationship != null) { + delete(relationship); + } + + + + } + + @Override + public List listByProduct(Product product) throws ServiceException { + + return productRelationshipRepository.listByProducts(product); + + } + + + @Override + public List getByType(MerchantStore store, Product product, ProductRelationshipType type, Language language) throws ServiceException { + + return productRelationshipRepository.getByType(store, type.name(), product, language); + + } + + @Override + public List getByType(MerchantStore store, ProductRelationshipType type, Language language) throws ServiceException { + return productRelationshipRepository.getByType(store, type.name(), language); + } + + @Override + public List getByType(MerchantStore store, ProductRelationshipType type) throws ServiceException { + + return productRelationshipRepository.getByType(store, type.name()); + + } + + @Override + public List getByGroup(MerchantStore store, String groupName) throws ServiceException { + + return productRelationshipRepository.getByType(store, groupName); + + } + + @Override + public List getByGroup(MerchantStore store, String groupName, Language language) throws ServiceException { + + return productRelationshipRepository.getByType(store, groupName, language); + + } + + @Override + public List getByType(MerchantStore store, Product product, ProductRelationshipType type) throws ServiceException { + + + return productRelationshipRepository.getByType(store, type.name(), product); + + + } + + @Override + public List getGroupDefinition(MerchantStore store, String name) { + return productRelationshipRepository.getByGroup(store, name); + } + + @Override + public List getByType(MerchantStore store, Product product, String name) + throws ServiceException { + return productRelationshipRepository.getByTypeAndRelatedProduct(store, name, product); + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/review/ProductReviewService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/review/ProductReviewService.java new file mode 100755 index 0000000000..2a6aba5808 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/review/ProductReviewService.java @@ -0,0 +1,27 @@ +package com.salesmanager.core.business.services.catalog.product.review; + +import java.util.List; + +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.review.ProductReview; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.reference.language.Language; + +public interface ProductReviewService extends + SalesManagerEntityService { + + + List getByCustomer(Customer customer); + List getByProduct(Product product); + List getByProduct(Product product, Language language); + ProductReview getByProductAndCustomer(Long productId, Long customerId); + /** + * @param product + * @return + */ + List getByProductNoCustomers(Product product); + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/review/ProductReviewServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/review/ProductReviewServiceImpl.java new file mode 100755 index 0000000000..e4068ce24f --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/review/ProductReviewServiceImpl.java @@ -0,0 +1,118 @@ +package com.salesmanager.core.business.services.catalog.product.review; + +import java.math.BigDecimal; +import java.util.List; + +import javax.inject.Inject; + +import org.apache.commons.lang3.Validate; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.catalog.product.review.ProductReviewRepository; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.review.ProductReview; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.reference.language.Language; + +@Service("productReviewService") +public class ProductReviewServiceImpl extends + SalesManagerEntityServiceImpl implements + ProductReviewService { + + + private ProductReviewRepository productReviewRepository; + + @Inject + private ProductService productService; + + @Inject + public ProductReviewServiceImpl( + ProductReviewRepository productReviewRepository) { + super(productReviewRepository); + this.productReviewRepository = productReviewRepository; + } + + @Override + public List getByCustomer(Customer customer) { + return productReviewRepository.findByCustomer(customer.getId()); + } + + @Override + public List getByProduct(Product product) { + return productReviewRepository.findByProduct(product.getId()); + } + + @Override + public ProductReview getByProductAndCustomer(Long productId, Long customerId) { + return productReviewRepository.findByProductAndCustomer(productId, customerId); + } + + @Override + public List getByProduct(Product product, Language language) { + return productReviewRepository.findByProduct(product.getId(), language.getId()); + } + + private void saveOrUpdate(ProductReview review) throws ServiceException { + + + Validate.notNull(review,"ProductReview cannot be null"); + Validate.notNull(review.getProduct(),"ProductReview.product cannot be null"); + Validate.notNull(review.getCustomer(),"ProductReview.customer cannot be null"); + + + //refresh product + Product product = productService.getById(review.getProduct().getId()); + + //ajust product rating + Integer count = 0; + if(product.getProductReviewCount()!=null) { + count = product.getProductReviewCount(); + } + + + + + BigDecimal averageRating = product.getProductReviewAvg(); + if(averageRating==null) { + averageRating = new BigDecimal(0); + } + //get reviews + + + BigDecimal totalRating = averageRating.multiply(new BigDecimal(count)); + totalRating = totalRating.add(new BigDecimal(review.getReviewRating())); + + count = count + 1; + double avg = totalRating.doubleValue() / count; + + product.setProductReviewAvg(new BigDecimal(avg)); + product.setProductReviewCount(count); + super.save(review); + + productService.update(product); + + review.setProduct(product); + + } + + public void update(ProductReview review) throws ServiceException { + this.saveOrUpdate(review); + } + + public void create(ProductReview review) throws ServiceException { + this.saveOrUpdate(review); + } + + /* (non-Javadoc) + * @see com.salesmanager.core.business.services.catalog.product.review.ProductReviewService#getByProductNoObjects(com.salesmanager.core.model.catalog.product.Product) + */ + @Override + public List getByProductNoCustomers(Product product) { + return productReviewRepository.findByProductNoCustomers(product.getId()); + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/type/ProductTypeService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/type/ProductTypeService.java new file mode 100755 index 0000000000..26e0aadf82 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/type/ProductTypeService.java @@ -0,0 +1,25 @@ +package com.salesmanager.core.business.services.catalog.product.type; + +import java.util.List; + +import org.springframework.data.domain.Page; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +public interface ProductTypeService extends SalesManagerEntityService { + + ProductType getProductType(String productTypeCode); + Page getByMerchant(MerchantStore store, Language language, int page, int count) throws ServiceException; + ProductType getByCode(String code, MerchantStore store, Language language) throws ServiceException; + ProductType getById(Long id, MerchantStore store, Language language) throws ServiceException; + ProductType getById(Long id, MerchantStore store) throws ServiceException; + void update(String code, MerchantStore store, ProductType type) throws ServiceException; + ProductType saveOrUpdate(ProductType productType) throws ServiceException; + List listProductTypes(List ids, MerchantStore store, Language language) throws ServiceException; + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/type/ProductTypeServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/type/ProductTypeServiceImpl.java new file mode 100755 index 0000000000..5c6436ace4 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/type/ProductTypeServiceImpl.java @@ -0,0 +1,86 @@ +package com.salesmanager.core.business.services.catalog.product.type; + +import java.util.List; + +import javax.inject.Inject; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.catalog.product.type.PageableProductTypeRepository; +import com.salesmanager.core.business.repositories.catalog.product.type.ProductTypeRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +@Service("productTypeService") +public class ProductTypeServiceImpl extends SalesManagerEntityServiceImpl + implements ProductTypeService { + + private ProductTypeRepository productTypeRepository; + + @Autowired + private PageableProductTypeRepository pageableProductTypeRepository; + + @Inject + public ProductTypeServiceImpl(ProductTypeRepository productTypeRepository) { + super(productTypeRepository); + this.productTypeRepository = productTypeRepository; + } + + @Override + public ProductType getByCode(String code, MerchantStore store, Language language) throws ServiceException { + return productTypeRepository.findByCode(code, store.getId()); + } + + @Override + public void update(String code, MerchantStore store, ProductType type) throws ServiceException { + productTypeRepository.save(type); + + } + + @Override + public ProductType getProductType(String productTypeCode) { + return productTypeRepository.findByCode(productTypeCode); + } + + @Override + public Page getByMerchant(MerchantStore store, Language language, int page, int count) throws ServiceException { + Pageable pageRequest = PageRequest.of(page, count); + return pageableProductTypeRepository.listByStore(store.getId(), pageRequest); + } + + @Override + public ProductType getById(Long id, MerchantStore store, Language language) throws ServiceException { + return productTypeRepository.findById(id, store.getId(), language.getId()); + } + + @Override + public ProductType saveOrUpdate(ProductType productType) throws ServiceException { + if(productType.getId()!=null && productType.getId() > 0) { + this.update(productType); + } else { + productType = super.saveAndFlush(productType); + } + + return productType; + } + + @Override + public List listProductTypes(List ids, MerchantStore store, Language language) + throws ServiceException { + return productTypeRepository.findByIds(ids, store.getId(), language.getId()); + } + + @Override + public ProductType getById(Long id, MerchantStore store) throws ServiceException { + return productTypeRepository.findById(id, store.getId()); + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantGroupService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantGroupService.java new file mode 100644 index 0000000000..d06e1ffce3 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantGroupService.java @@ -0,0 +1,25 @@ +package com.salesmanager.core.business.services.catalog.product.variant; + +import java.util.Optional; + +import org.springframework.data.domain.Page; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.product.variant.ProductVariantGroup; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +public interface ProductVariantGroupService extends SalesManagerEntityService { + + + Optional getById(Long id, MerchantStore store); + + Optional getByProductVariant(Long productVariantId, MerchantStore store, Language language); + + Page getByProductId(MerchantStore store, Long productId, Language language, int page, int count); + + ProductVariantGroup saveOrUpdate(ProductVariantGroup entity) throws ServiceException; + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantGroupServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantGroupServiceImpl.java new file mode 100644 index 0000000000..dbb41060e2 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantGroupServiceImpl.java @@ -0,0 +1,63 @@ +package com.salesmanager.core.business.services.catalog.product.variant; + +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.catalog.product.variant.PageableProductVariantGroupRepository; +import com.salesmanager.core.business.repositories.catalog.product.variant.ProductVariantGroupRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.product.variant.ProductVariantGroup; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + + +@Service("productVariantGroupService") +public class ProductVariantGroupServiceImpl extends SalesManagerEntityServiceImpl implements ProductVariantGroupService { + + + @Autowired + private PageableProductVariantGroupRepository pageableProductVariantGroupRepository; + + private ProductVariantGroupRepository productVariantGroupRepository; + + public ProductVariantGroupServiceImpl(ProductVariantGroupRepository repository) { + super(repository); + this.productVariantGroupRepository = repository; + } + + @Override + public Optional getById(Long id, MerchantStore store) { + return productVariantGroupRepository.findOne(id, store.getCode()); + + } + + @Override + public Optional getByProductVariant(Long productVariantId, MerchantStore store, + Language language) { + return productVariantGroupRepository.finByProductVariant(productVariantId, store.getCode()); + } + + @Override + public ProductVariantGroup saveOrUpdate(ProductVariantGroup entity) throws ServiceException { + + entity = productVariantGroupRepository.save(entity); + return entity; + + } + + @Override + public Page getByProductId(MerchantStore store, Long productId, Language language, int page, + int count) { + + Pageable pageRequest = PageRequest.of(page, count); + return pageableProductVariantGroupRepository.findByProductId(store.getId(), productId, pageRequest); + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantImageService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantImageService.java new file mode 100644 index 0000000000..8205b82aac --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantImageService.java @@ -0,0 +1,16 @@ +package com.salesmanager.core.business.services.catalog.product.variant; + +import java.util.List; + +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.product.variant.ProductVariantImage; +import com.salesmanager.core.model.merchant.MerchantStore; + +public interface ProductVariantImageService extends SalesManagerEntityService { + + + List list(Long productVariantId, MerchantStore store); + List listByProduct(Long productId, MerchantStore store); + List listByProductVariantGroup(Long productVariantGroupId, MerchantStore store); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantImageServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantImageServiceImpl.java new file mode 100644 index 0000000000..415b653d38 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantImageServiceImpl.java @@ -0,0 +1,44 @@ +package com.salesmanager.core.business.services.catalog.product.variant; + +import java.util.List; + +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.repositories.catalog.product.variant.ProductVariantImageRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.product.variant.ProductVariantImage; +import com.salesmanager.core.model.merchant.MerchantStore; + + +@Service("productVariantImageService") +public class ProductVariantImageServiceImpl extends SalesManagerEntityServiceImpl implements ProductVariantImageService { + + @Autowired + private ProductVariantImageRepository productVariantImageRepository; + + public ProductVariantImageServiceImpl(ProductVariantImageRepository productVariantImageRepository) { + super(productVariantImageRepository); + this.productVariantImageRepository = productVariantImageRepository; + } + + @Override + public List list(Long productVariantId, MerchantStore store) { + Validate.notNull(store, "MerchantStore cannot be null"); + return productVariantImageRepository.finByProductVariant(productVariantId, store.getCode()); + } + + @Override + public List listByProduct(Long productId, MerchantStore store) { + Validate.notNull(store, "MerchantStore cannot be null"); + return productVariantImageRepository.finByProduct(productId, store.getCode()); + } + + @Override + public List listByProductVariantGroup(Long productVariantGroupId, MerchantStore store) { + Validate.notNull(store, "MerchantStore cannot be null"); + return productVariantImageRepository.finByProductVariantGroup(productVariantGroupId, store.getCode()); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantService.java new file mode 100644 index 0000000000..2f55c43287 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantService.java @@ -0,0 +1,37 @@ +package com.salesmanager.core.business.services.catalog.product.variant; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.domain.Page; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +public interface ProductVariantService extends SalesManagerEntityService { + + Optional getById(Long id, Long productId, MerchantStore store); + + List getByIds(List ids, MerchantStore store); + + Optional getById(Long id, MerchantStore store); + + Optional getBySku(String sku, Long productId, MerchantStore store, Language language); + + List getByProductId(MerchantStore store, Product product, Language language); + + + Page getByProductId(MerchantStore store, Product product, Language language, int page, int count); + + + boolean exist(String sku, Long productId); + + ProductVariant saveProductVariant(ProductVariant variant) throws ServiceException; + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantServiceImpl.java new file mode 100644 index 0000000000..7dc6b1b7cd --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variant/ProductVariantServiceImpl.java @@ -0,0 +1,92 @@ +package com.salesmanager.core.business.services.catalog.product.variant; + +import java.util.List; +import java.util.Optional; + +import javax.inject.Inject; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.catalog.product.variant.PageableProductVariantRepositoty; +import com.salesmanager.core.business.repositories.catalog.product.variant.ProductVariantRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +@Service("productVariantService") +public class ProductVariantServiceImpl extends SalesManagerEntityServiceImpl + implements ProductVariantService { + + + private ProductVariantRepository productVariantRepository; + + @Autowired + private PageableProductVariantRepositoty pageableProductVariantRepositoty; + + @Inject + public ProductVariantServiceImpl(ProductVariantRepository productVariantRepository) { + super(productVariantRepository); + this.productVariantRepository = productVariantRepository; + } + + @Override + public Optional getById(Long id, Long productId, MerchantStore store) { + return productVariantRepository.findById(id, productId, store.getId()); + } + + public Page getByProductId(MerchantStore store, Product product, Language language, int page, + int count) { + Pageable pageRequest = PageRequest.of(page, count); + return pageableProductVariantRepositoty.findByProductId(store.getId(), product.getId(), pageRequest); + } + + @Override + public List getByProductId(MerchantStore store, Product product, Language language) { + return productVariantRepository.findByProductId(store.getId(), product.getId()); + } + + @Override + public Optional getBySku(String sku, Long productId, MerchantStore store, Language language) { + return productVariantRepository.findBySku(sku, productId, store.getId(), language.getId()); + } + + @Override + public boolean exist(String sku, Long productId) { + + ProductVariant instance = productVariantRepository.existsBySkuAndProduct(sku, productId); + return instance != null? true:false; + + } + + @Override + public Optional getById(Long id, MerchantStore store) { + + return productVariantRepository.findOne(id,store.getId()); + } + + @Override + public List getByIds(List ids, MerchantStore store) { + + return productVariantRepository.findByIds(ids, store.getId()); + } + + @Override + public ProductVariant saveProductVariant(ProductVariant variant) throws ServiceException { + + variant = productVariantRepository.save(variant); + return variant; + } + + @Override + public void delete(ProductVariant instance) throws ServiceException{ + super.delete(instance); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variation/ProductVariationService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variation/ProductVariationService.java new file mode 100755 index 0000000000..0d16dd3b5e --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variation/ProductVariationService.java @@ -0,0 +1,29 @@ +package com.salesmanager.core.business.services.catalog.product.variation; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.domain.Page; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.product.variation.ProductVariation; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +public interface ProductVariationService extends SalesManagerEntityService { + + + void saveOrUpdate(ProductVariation entity) throws ServiceException; + + Optional getById(MerchantStore store, Long id, Language lang); + + Optional getById(MerchantStore store, Long id); + + Optional getByCode(MerchantStore store, String code); + + Page getByMerchant(MerchantStore store, Language language, String code, int page, int count); + + List getByIds(List ids, MerchantStore store); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variation/ProductVariationServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variation/ProductVariationServiceImpl.java new file mode 100755 index 0000000000..af1a828ada --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/catalog/product/variation/ProductVariationServiceImpl.java @@ -0,0 +1,89 @@ +package com.salesmanager.core.business.services.catalog.product.variation; + +import java.util.List; +import java.util.Optional; + +import javax.inject.Inject; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.catalog.product.variation.PageableProductVariationRepository; +import com.salesmanager.core.business.repositories.catalog.product.variation.ProductVariationRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.product.variation.ProductVariation; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +@Service("productVariationeService") +public class ProductVariationServiceImpl extends + SalesManagerEntityServiceImpl implements + ProductVariationService { + + @Inject + private ProductVariationRepository productVariationRepository; + + @Inject + public ProductVariationServiceImpl( + ProductVariationRepository productVariationSetRepository) { + super(productVariationSetRepository); + this.productVariationRepository = productVariationSetRepository; + } + + + @Autowired + private PageableProductVariationRepository pageableProductVariationSetRepository; + + + @Override + public Optional getById(MerchantStore store, Long id, Language lang) { + return productVariationRepository.findOne(store.getId(), id, lang.getId()); + } + + @Override + public Optional getByCode(MerchantStore store, String code) { + return productVariationRepository.findByCode(code, store.getId()); + } + + + + @Override + public Page getByMerchant(MerchantStore store, Language language, String code, int page, + int count) { + Pageable p = PageRequest.of(page, count); + return pageableProductVariationSetRepository.list(store.getId(), code, p); + } + + @Override + public Optional getById(MerchantStore store, Long id) { + return productVariationRepository.findOne(store.getId(), id); + } + + @Override + public void saveOrUpdate(ProductVariation entity) throws ServiceException { + + //save or update (persist and attach entities + if(entity.getId()!=null && entity.getId()>0) { + + super.update(entity); + + } else { + + super.save(entity); + + } + + } + + @Override + public List getByIds(List ids, MerchantStore store) { + return productVariationRepository.findByIds(store.getId(), ids); + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/common/generic/SalesManagerEntityService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/common/generic/SalesManagerEntityService.java new file mode 100755 index 0000000000..23f409b960 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/common/generic/SalesManagerEntityService.java @@ -0,0 +1,82 @@ +package com.salesmanager.core.business.services.common.generic; + +import java.io.Serializable; +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; + + +/** + *

    Service racine pour la gestion des entités.

    + * + * @param type d'entité + */ +public interface SalesManagerEntityService, E extends com.salesmanager.core.model.generic.SalesManagerEntity> extends TransactionalAspectAwareService{ + + /** + * Crée l'entité dans la base de données. Mis à part dans les tests pour faire des sauvegardes simples, utiliser + * create() car il est possible qu'il y ait des listeners sur la création d'une entité. + * + * @param entity entité + */ + void save(E entity) throws ServiceException; + + /** + * Save all + */ + void saveAll(Iterable entities) throws ServiceException; + + /** + * Met à jour l'entité dans la base de données. + * + * @param entity entité + */ + void update(E entity) throws ServiceException; + + /** + * Crée l'entité dans la base de données. + * + * @param entity entité + */ + void create(E entity) throws ServiceException; + + + /** + * Supprime l'entité de la base de données + * + * @param entity entité + */ + void delete(E entity) throws ServiceException; + + + /** + * Retourne une entité à partir de son id. + * + * @param id identifiant + * @return entité + */ + E getById(K id); + + /** + * Renvoie la liste de l'ensemble des entités de ce type. + * + * @return liste d'entités + */ + List list(); + + + /** + * Compte le nombre d'entités de ce type présentes dans la base. + * + * @return nombre d'entités + */ + Long count(); + + /** + * Flushe la session. + */ + void flush(); + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/common/generic/SalesManagerEntityServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/common/generic/SalesManagerEntityServiceImpl.java new file mode 100755 index 0000000000..994bbfcc5a --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/common/generic/SalesManagerEntityServiceImpl.java @@ -0,0 +1,87 @@ +package com.salesmanager.core.business.services.common.generic; + +import java.io.Serializable; +import java.lang.reflect.ParameterizedType; +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.generic.SalesManagerEntity; + +/** + * @param entity type + */ +public abstract class SalesManagerEntityServiceImpl, E extends SalesManagerEntity> + implements SalesManagerEntityService { + + /** + * Classe de l'entité, déterminé à partir des paramètres generics. + */ + private Class objectClass; + + + private JpaRepository repository; + + @SuppressWarnings("unchecked") + public SalesManagerEntityServiceImpl(JpaRepository repository) { + ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass(); + this.objectClass = (Class) genericSuperclass.getActualTypeArguments()[1]; + this.repository = repository; + } + + protected final Class getObjectClass() { + return objectClass; + } + + + public E getById(K id) { + return repository.getOne(id); + } + + + public void save(E entity) throws ServiceException { + repository.saveAndFlush(entity); + } + + public void saveAll(Iterable entities) throws ServiceException { + repository.saveAll(entities); + } + + + public void create(E entity) throws ServiceException { + save(entity); + } + + + + public void update(E entity) throws ServiceException { + save(entity); + } + + + public void delete(E entity) throws ServiceException { + repository.delete(entity); + } + + + public void flush() { + repository.flush(); + } + + + + public List list() { + return repository.findAll(); + } + + + public Long count() { + return repository.count(); + } + + protected E saveAndFlush(E entity) { + return repository.saveAndFlush(entity); + } + +} \ No newline at end of file diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/common/generic/TransactionalAspectAwareService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/common/generic/TransactionalAspectAwareService.java new file mode 100755 index 0000000000..417b314101 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/common/generic/TransactionalAspectAwareService.java @@ -0,0 +1,12 @@ +package com.salesmanager.core.business.services.common.generic; + +/** + * Indique que le service doit être rendu transactionnel via un aspect. + * + * Cela permet de simplifier la configuration Spring de la partie transactionnelle car + * il suffit alors de déclarer le pointcut de l'aspect sur + * this(com.salesmanager.core.business.services.common.generic.ITransactionalAspectAwareService) + */ +public interface TransactionalAspectAwareService { + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/content/ContentService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/content/ContentService.java new file mode 100755 index 0000000000..2ec78f4895 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/content/ContentService.java @@ -0,0 +1,198 @@ +package com.salesmanager.core.business.services.content; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.domain.Page; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.content.Content; +import com.salesmanager.core.model.content.ContentDescription; +import com.salesmanager.core.model.content.ContentType; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.InputContentFile; +import com.salesmanager.core.model.content.OutputContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + + +/** + * + * Interface defining methods responsible for CMSContentService. + * ContentServive will be be entry point for CMS and take care of following functionalities. + *
  • Adding,removing Content images for given merchant store
  • + *
  • Get,Save,Update Content data for given merchant store
  • + * + * @author Umesh Awasthhi + * @author Carl Samson + * + */ +public interface ContentService + extends SalesManagerEntityService +{ + + List listByType( ContentType contentType, MerchantStore store, Language language ) + throws ServiceException; + + List listByType( List contentType, MerchantStore store, Language language ) + throws ServiceException; + + Content getByCode( String code, MerchantStore store ) + throws ServiceException; + + void saveOrUpdate( Content content ) + throws ServiceException; + + boolean exists (String code, ContentType type, MerchantStore store); + + Content getByCode( String code, MerchantStore store, Language language ) + throws ServiceException; + + Content getById( Long id, MerchantStore store, Language language ) + throws ServiceException; + + Content getById( Long id, MerchantStore store) + throws ServiceException; + + /** + * Method responsible for storing content file for given Store.Files for given merchant store will be stored in + * Infinispan. + * + * @param merchantStoreCode merchant store whose content images are being saved. + * @param contentFile content image being stored + * @throws ServiceException + */ + void addContentFile( String merchantStoreCode, InputContentFile contentFile ) + throws ServiceException; + + + /** + * Method responsible for storing list of content image for given Store.Images for given merchant store will be stored in + * Infinispan. + * + * @param merchantStoreCode merchant store whose content images are being saved. + * @param contentImagesList list of content images being stored. + * @throws ServiceException + */ + void addContentFiles(String merchantStoreCode,List contentFilesList) throws ServiceException; + + + /** + * Method to remove given content image.Images are stored in underlying system based on there name. + * Name will be used to search given image for removal + * @param imageContentType + * @param imageName + * @param merchantStoreCode merchant store code + * @throws ServiceException + */ + void removeFile( String merchantStoreCode, FileContentType fileContentType, String fileName) throws ServiceException; + + /** + * Removes static file + * FileType is no more important + * @param storeCode + * @param filename + */ + void removeFile(String storeCode, String filename) throws ServiceException; + + /** + * Method to remove all images for a given merchant.It will take merchant store as an input and will + * remove all images associated with given merchant store. + * + * @param merchantStoreCode + * @throws ServiceException + */ + void removeFiles( String merchantStoreCode ) throws ServiceException; + + /** + * Rename file + * @param merchantStoreCode + * @param path + * @param originalName + * @param newName + */ + void renameFile( String merchantStoreCode, FileContentType fileContentType, Optional path, String originalName, String newName) throws ServiceException; + + /** + * Method responsible for fetching particular content image for a given merchant store. Requested image will be + * search in Infinispan tree cache and OutputContentImage will be sent, in case no image is found null will + * returned. + * + * @param merchantStoreCode + * @param imageName + * @return {@link OutputContentImage} + * @throws ServiceException + */ + OutputContentFile getContentFile( String merchantStoreCode, FileContentType fileContentType, String fileName ) + throws ServiceException; + + + /** + * Method to get list of all images associated with a given merchant store.In case of no image method will return an empty list. + * @param merchantStoreCode + * @param imageContentType + * @return list of {@link OutputContentImage} + * @throws ServiceException + */ + List getContentFiles( String merchantStoreCode, FileContentType fileContentType ) + throws ServiceException; + + + List getContentFilesNames(String merchantStoreCode, + FileContentType fileContentType) throws ServiceException; + + /** + * Add the store logo + * @param merchantStoreCode + * @param cmsContentImage + * @throws ServiceException + */ + void addLogo(String merchantStoreCode, InputContentFile cmsContentImage) + throws ServiceException; + + /** + * Adds a property (option) image + * @param merchantStoreId + * @param cmsContentImage + * @throws ServiceException + */ + void addOptionImage(String merchantStoreCode, InputContentFile cmsContentImage) + throws ServiceException; + + + + List listByType(List contentType, MerchantStore store) + throws ServiceException; + + Page listByType(ContentType contentType, MerchantStore store, int page, int count) + throws ServiceException; + + Page listByType(ContentType contentType, MerchantStore store, Language language, int page, int count) + throws ServiceException; + + List listNameByType(List contentType, + MerchantStore store, Language language) throws ServiceException; + + Content getByLanguage(Long id, Language language) throws ServiceException; + + ContentDescription getBySeUrl(MerchantStore store, String seUrl); + + /** + * Finds content for a specific Merchant for a specific ContentType where content + * code is like a given prefix in a specific language + * @param type + * @param codeLike + * @param store + * @param lamguage + * @return + */ + List getByCodeLike(ContentType type, String codeLike, MerchantStore store, Language language); + + void addFolder(MerchantStore store, Optional path, String folderName) throws ServiceException ; + + List listFolders(MerchantStore store, Optional path) throws ServiceException ; + + void removeFolder(MerchantStore store, Optional path, String folderName) throws ServiceException ; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/content/ContentServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/content/ContentServiceImpl.java new file mode 100755 index 0000000000..d1ae393249 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/content/ContentServiceImpl.java @@ -0,0 +1,542 @@ +package com.salesmanager.core.business.services.content; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.net.URLConnection; +import java.util.List; +import java.util.Optional; +import java.util.regex.Pattern; + +import javax.inject.Inject; + +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.util.Assert; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.cms.content.StaticContentFileManager; +import com.salesmanager.core.business.repositories.content.ContentRepository; +import com.salesmanager.core.business.repositories.content.PageContentRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.content.Content; +import com.salesmanager.core.model.content.ContentDescription; +import com.salesmanager.core.model.content.ContentType; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.InputContentFile; +import com.salesmanager.core.model.content.OutputContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +@Service("contentService") +public class ContentServiceImpl extends SalesManagerEntityServiceImpl implements ContentService { + + private static final Logger LOG = LoggerFactory.getLogger(ContentServiceImpl.class); + + private final ContentRepository contentRepository; + + @Autowired + private PageContentRepository pageContentRepository; + + + @Inject + StaticContentFileManager contentFileManager; + + @Inject + public ContentServiceImpl(ContentRepository contentRepository) { + super(contentRepository); + + this.contentRepository = contentRepository; + } + + @Override + public List listByType(ContentType contentType, MerchantStore store, Language language) + throws ServiceException { + + return contentRepository.findByType(contentType, store.getId(), language.getId()); + } + + @Override + public void delete(Content content) throws ServiceException { + + Content c = this.getById(content.getId()); + super.delete(c); + + } + + @Override + public Content getByLanguage(Long id, Language language) throws ServiceException { + return contentRepository.findByIdAndLanguage(id, language.getId()); + } + + @Override + public List listByType(List contentType, MerchantStore store, Language language) + throws ServiceException { + + /* + * List contentTypes = new ArrayList(); for (int i = 0; + * i < contentType.size(); i++) { + * contentTypes.add(contentType.get(i).name()); } + */ + + return contentRepository.findByTypes(contentType, store.getId(), language.getId()); + } + + @Override + public List listNameByType(List contentType, MerchantStore store, + Language language) throws ServiceException { + + return contentRepository.listNameByType(contentType, store, language); + } + + @Override + public List listByType(List contentType, MerchantStore store) throws ServiceException { + + return contentRepository.findByTypes(contentType, store.getId()); + } + + @Override + public Content getByCode(String code, MerchantStore store) throws ServiceException { + + return contentRepository.findByCode(code, store.getId()); + + } + + @Override + public Content getById(Long id) { + return contentRepository.findOne(id); + } + + @Override + public void saveOrUpdate(final Content content) throws ServiceException { + + // save or update (persist and attach entities + if (content.getId() != null && content.getId() > 0) { + super.update(content); + } else { + super.save(content); + } + + } + + @Override + public Content getByCode(String code, MerchantStore store, Language language) throws ServiceException { + return contentRepository.findByCode(code, store.getId(), language.getId()); + } + + /** + * Method responsible for adding content file for given merchant store in + * underlying Infinispan tree cache. It will take {@link InputContentFile} + * and will store file for given merchant store according to its type. it + * can save an image or any type of file (pdf, css, js ...) + * + * @param merchantStoreCode + * Merchant store + * @param contentFile + * {@link InputContentFile} being stored + * @throws ServiceException + * service exception + */ + @Override + public void addContentFile(String merchantStoreCode, InputContentFile contentFile) throws ServiceException { + Assert.notNull(merchantStoreCode, "Merchant store Id can not be null"); + Assert.notNull(contentFile, "InputContentFile image can not be null"); + Assert.notNull(contentFile.getFileName(), "InputContentFile.fileName can not be null"); + Assert.notNull(contentFile.getFileContentType(), "InputContentFile.fileContentType can not be null"); + + String mimeType = URLConnection.guessContentTypeFromName(contentFile.getFileName()); + contentFile.setMimeType(mimeType); + + if (contentFile.getFileContentType().name().equals(FileContentType.IMAGE.name()) + || contentFile.getFileContentType().name().equals(FileContentType.STATIC_FILE.name())) { + addFile(merchantStoreCode, contentFile); + } else if(contentFile.getFileContentType().name().equals(FileContentType.API_IMAGE.name())) { + contentFile.setFileContentType(FileContentType.IMAGE); + addImage(merchantStoreCode, contentFile); + } else if(contentFile.getFileContentType().name().equals(FileContentType.API_FILE.name())) { + contentFile.setFileContentType(FileContentType.STATIC_FILE); + addFile(merchantStoreCode, contentFile); + } else { + addImage(merchantStoreCode, contentFile); + } + + } + + @Override + public void addLogo(String merchantStoreCode, InputContentFile cmsContentImage) throws ServiceException { + + Assert.notNull(merchantStoreCode, "Merchant store Id can not be null"); + Assert.notNull(cmsContentImage, "CMSContent image can not be null"); + + cmsContentImage.setFileContentType(FileContentType.LOGO); + addImage(merchantStoreCode, cmsContentImage); + + } + + @Override + public void addOptionImage(String merchantStoreCode, InputContentFile cmsContentImage) throws ServiceException { + + Assert.notNull(merchantStoreCode, "Merchant store Id can not be null"); + Assert.notNull(cmsContentImage, "CMSContent image can not be null"); + cmsContentImage.setFileContentType(FileContentType.PROPERTY); + addImage(merchantStoreCode, cmsContentImage); + + } + + private void addImage(String merchantStoreCode, InputContentFile contentImage) throws ServiceException { + + try { + LOG.info("Adding content image for merchant id {}", merchantStoreCode); + + String p = contentImage.getPath(); + Optional path = Optional.ofNullable(p); + contentFileManager.addFile(merchantStoreCode, path, contentImage); + + } catch (Exception e) { + LOG.error("Error while trying to convert input stream to buffered image", e); + throw new ServiceException(e); + + } finally { + + try { + if (contentImage.getFile() != null) { + contentImage.getFile().close(); + } + } catch (Exception ignore) { + } + + } + + } + + private void addFile(final String merchantStoreCode, InputContentFile contentImage) throws ServiceException { + + try { + LOG.info("Adding content file for merchant id {}", merchantStoreCode); + // staticContentFileManager.addFile(merchantStoreCode, + // contentImage); + + String p = null; + Optional path = Optional.ofNullable(p); + + contentFileManager.addFile(merchantStoreCode, path, contentImage); + + } catch (Exception e) { + LOG.error("Error while trying to convert input stream to buffered image", e); + throw new ServiceException(e); + + } finally { + + try { + if (contentImage.getFile() != null) { + contentImage.getFile().close(); + } + } catch (Exception ignore) { + } + } + + } + + /** + * Method responsible for adding list of content images for given merchant + * store in underlying Infinispan tree cache. It will take list of + * {@link CMSContentImage} and will store them for given merchant store. + * + * @param merchantStoreCode + * Merchant store + * @param contentImagesList + * list of {@link CMSContentImage} being stored + * @throws ServiceException + * service exception + */ + @Override + public void addContentFiles(String merchantStoreCode, List contentFilesList) + throws ServiceException { + + Assert.notNull(merchantStoreCode, "Merchant store ID can not be null"); + Assert.notEmpty(contentFilesList, "File list can not be empty"); + LOG.info("Adding total {} images for given merchant", contentFilesList.size()); + + String p = null; + Optional path = Optional.ofNullable(p); + + LOG.info("Adding content images for merchant...."); + contentFileManager.addFiles(merchantStoreCode, path, contentFilesList); + // staticContentFileManager.addFiles(merchantStoreCode, + // contentFilesList); + + try { + for (InputContentFile file : contentFilesList) { + if (file.getFile() != null) { + file.getFile().close(); + } + } + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + /** + * Method to remove given content image.Images are stored in underlying + * system based on there name. Name will be used to search given image for + * removal + * + * @param contentImage + * @param merchantStoreCode + * merchant store + * @throws ServiceException + */ + @Override + public void removeFile(String merchantStoreCode, FileContentType fileContentType, String fileName) + throws ServiceException { + Assert.notNull(merchantStoreCode, "Merchant Store Id can not be null"); + Assert.notNull(fileContentType, "Content file type can not be null"); + Assert.notNull(fileName, "Content Image type can not be null"); + + String p = null; + Optional path = Optional.ofNullable(p); + + contentFileManager.removeFile(merchantStoreCode, fileContentType, fileName, path); + + } + + @Override + public void removeFile(String storeCode, String fileName) throws ServiceException { + + String fileType = "IMAGE"; + String mimetype = URLConnection.guessContentTypeFromName(fileName); + String type = mimetype.split("/")[0]; + if (!type.equals("image")) + fileType = "STATIC_FILE"; + + String p = null; + Optional path = Optional.ofNullable(p); + + contentFileManager.removeFile(storeCode, FileContentType.valueOf(fileType), fileName, path); + + } + + /** + * Method to remove all images for a given merchant.It will take merchant + * store as an input and will remove all images associated with given + * merchant store. + * + * @param merchantStoreCode + * @throws ServiceException + */ + @Override + public void removeFiles(String merchantStoreCode) throws ServiceException { + Assert.notNull(merchantStoreCode, "Merchant Store Id can not be null"); + + String p = null; + Optional path = Optional.ofNullable(p); + + contentFileManager.removeFiles(merchantStoreCode, path); + } + + /** + * Implementation for getContentImage method defined in + * {@link ContentService} interface. Methods will return Content image with + * given image name for the Merchant store or will return null if no image + * with given name found for requested Merchant Store in Infinispan tree + * cache. + * + * @param store + * Merchant merchantStoreCode + * @param imageName + * name of requested image + * @return {@link OutputContentImage} + * @throws ServiceException + */ + @Override + public OutputContentFile getContentFile(String merchantStoreCode, FileContentType fileContentType, String fileName) + throws ServiceException { + Assert.notNull(merchantStoreCode, "Merchant store ID can not be null"); + Assert.notNull(fileName, "File name can not be null"); + + String p = null; + Optional path = Optional.ofNullable(p); + + return contentFileManager.getFile(merchantStoreCode, path, fileContentType, fileName); + + } + + /** + * Implementation for getContentImages method defined in + * {@link ContentService} interface. Methods will return list of all Content + * image associated with given Merchant store or will return empty list if + * no image is associated with given Merchant Store in Infinispan tree + * cache. + * + * @param merchantStoreId + * Merchant store + * @return list of {@link OutputContentImage} + * @throws ServiceException + */ + @Override + public List getContentFiles(String merchantStoreCode, FileContentType fileContentType) + throws ServiceException { + Assert.notNull(merchantStoreCode, "Merchant store Id can not be null"); + // return staticContentFileManager.getFiles(merchantStoreCode, + // fileContentType); + String p = null; + Optional path = Optional.ofNullable(p); + return contentFileManager.getFiles(merchantStoreCode, path, fileContentType); + } + + /** + * Returns the image names for a given merchant and store + * + * @param merchantStoreCode + * @param imageContentType + * @return images name list + * @throws ServiceException + */ + @Override + public List getContentFilesNames(String merchantStoreCode, FileContentType fileContentType) + throws ServiceException { + Assert.notNull(merchantStoreCode, "Merchant store Id can not be null"); + + String p = null; + Optional path = Optional.ofNullable(p); + + return contentFileManager.getFileNames(merchantStoreCode, path, fileContentType); + + /* + * if(fileContentType.name().equals(FileContentType.IMAGE.name()) || + * fileContentType.name().equals(FileContentType.STATIC_FILE.name())) { + * return contentFileManager.getFileNames(merchantStoreCode, + * fileContentType); } else { return + * contentFileManager.getFileNames(merchantStoreCode, fileContentType); + * } + */ + } + + @Override + public ContentDescription getBySeUrl(MerchantStore store, String seUrl) { + return contentRepository.getBySeUrl(store, seUrl); + } + + @Override + public List getByCodeLike(ContentType type, String codeLike, MerchantStore store, Language language) { + return contentRepository.findByCodeLike(type, '%' + codeLike + '%', store.getId(), language.getId()); + } + + @Override + public Content getById(Long id, MerchantStore store, Language language) throws ServiceException { + + Content content = contentRepository.findOne(id); + + if (content != null) { + if (content.getMerchantStore().getId().intValue() != store.getId().intValue()) { + return null; + } + } + + return content; + } + + public Content getById(Long id, MerchantStore store) throws ServiceException { + + Content content = contentRepository.findOne(id); + + if (content != null) { + if (content.getMerchantStore().getId().intValue() != store.getId().intValue()) { + return null; + } + } + + return content; + } + + @Override + public void addFolder(MerchantStore store, Optional path, String folderName) throws ServiceException { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(folderName, "Folder name cannot be null"); + + if(path.isPresent()) { + if(!this.isValidLinuxDirectory(path.get())) { + throw new ServiceException("Path format [" + path.get() + "] not a valid directory format"); + } + } + contentFileManager.addFolder(store.getCode(), folderName, path); + + + } + + @Override + public List listFolders(MerchantStore store, Optional path) throws ServiceException { + Validate.notNull(store, "MerchantStore cannot be null"); + + return contentFileManager.listFolders(store.getCode(), path); + } + + @Override + public void removeFolder(MerchantStore store, Optional path, String folderName) throws ServiceException { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(folderName, "Folder name cannot be null"); + + contentFileManager.removeFolder(store.getCode(), folderName, path); + + } + + public boolean isValidLinuxDirectory(String path) { + Pattern linuxDirectoryPattern = Pattern.compile("^/|(/[a-zA-Z0-9_-]+)+$"); + return path != null && !path.trim().isEmpty() && linuxDirectoryPattern.matcher( path ).matches(); + } + + @Override + public void renameFile(String merchantStoreCode, FileContentType fileContentType, Optional path, + String originalName, String newName) throws ServiceException{ + + OutputContentFile file = contentFileManager.getFile(merchantStoreCode, path, fileContentType, originalName); + + if(file == null) { + throw new ServiceException("File name [" + originalName + "] not found for merchant [" + merchantStoreCode +"]"); + } + + ByteArrayOutputStream os = file.getFile(); + InputStream is = new ByteArrayInputStream(os.toByteArray()); + + //remove file + contentFileManager.removeFile(merchantStoreCode, fileContentType, originalName, path); + + //recreate file + InputContentFile inputFile = new InputContentFile(); + inputFile.setFileContentType(fileContentType); + inputFile.setFileName(newName); + inputFile.setMimeType(file.getMimeType()); + inputFile.setFile(is); + + contentFileManager.addFile(merchantStoreCode, path, inputFile); + + } + + @Override + public Page listByType(ContentType contentType, MerchantStore store, int page, int count) + throws ServiceException { + Pageable pageRequest = PageRequest.of(page, count); + return pageContentRepository.findByContentType(contentType, store.getId(), pageRequest); + } + + @Override + public Page listByType(ContentType contentType, MerchantStore store, Language language, int page, + int count) throws ServiceException { + Pageable pageRequest = PageRequest.of(page, count); + return pageContentRepository.findByContentType(contentType, store.getId(), language.getId(), pageRequest); + } + + @Override + public boolean exists(String code, ContentType type, MerchantStore store) { + Content c = contentRepository.findByCodeAndType(code, type, store.getId()); + return c !=null ? true:false; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/customer/CustomerService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/CustomerService.java new file mode 100755 index 0000000000..2e8d8b3070 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/CustomerService.java @@ -0,0 +1,50 @@ +package com.salesmanager.core.business.services.customer; + + +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.common.Address; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.customer.CustomerCriteria; +import com.salesmanager.core.model.customer.CustomerList; +import com.salesmanager.core.model.merchant.MerchantStore; + + + +public interface CustomerService extends SalesManagerEntityService { + + List getByName(String firstName); + + List getListByStore(MerchantStore store); + + Customer getByNick(String nick); + + void saveOrUpdate(Customer customer) throws ServiceException ; + + CustomerList getListByStore(MerchantStore store, CustomerCriteria criteria); + + Customer getByNick(String nick, int storeId); + Customer getByNick(String nick, String code); + + /** + * Password reset token + * @param storeCode + * @param token + * @return + */ + Customer getByPasswordResetToken(String storeCode, String token); + + /** + * Return an {@link com.salesmanager.core.business.common.model.Address} object from the client IP address. Uses underlying GeoLocation module + * @param store + * @param ipAddress + * @return + * @throws ServiceException + */ + Address getCustomerAddress(MerchantStore store, String ipAddress) + throws ServiceException; + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/customer/CustomerServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/CustomerServiceImpl.java new file mode 100755 index 0000000000..1c80badb25 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/CustomerServiceImpl.java @@ -0,0 +1,125 @@ +package com.salesmanager.core.business.services.customer; + +import java.util.List; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.customer.CustomerRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.business.services.customer.attribute.CustomerAttributeService; +import com.salesmanager.core.model.common.Address; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.customer.CustomerCriteria; +import com.salesmanager.core.model.customer.CustomerList; +import com.salesmanager.core.model.customer.attribute.CustomerAttribute; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.modules.utils.GeoLocation; + + + +@Service("customerService") +public class CustomerServiceImpl extends SalesManagerEntityServiceImpl implements CustomerService { + + private static final Logger LOGGER = LoggerFactory.getLogger(CustomerServiceImpl.class); + + private CustomerRepository customerRepository; + + @Inject + private CustomerAttributeService customerAttributeService; + + @Inject + private GeoLocation geoLocation; + + + @Inject + public CustomerServiceImpl(CustomerRepository customerRepository) { + super(customerRepository); + this.customerRepository = customerRepository; + } + + @Override + public List getByName(String firstName) { + return customerRepository.findByName(firstName); + } + + @Override + public Customer getById(Long id) { + return customerRepository.findOne(id); + } + + @Override + public Customer getByNick(String nick) { + return customerRepository.findByNick(nick); + } + + @Override + public Customer getByNick(String nick, int storeId) { + return customerRepository.findByNick(nick, storeId); + } + + @Override + public List getListByStore(MerchantStore store) { + return customerRepository.findByStore(store.getId()); + } + + @Override + public CustomerList getListByStore(MerchantStore store, CustomerCriteria criteria) { + return customerRepository.listByStore(store,criteria); + } + + @Override + public Address getCustomerAddress(MerchantStore store, String ipAddress) throws ServiceException { + + try { + return geoLocation.getAddress(ipAddress); + } catch(Exception e) { + throw new ServiceException(e); + } + + } + + @Override + public void saveOrUpdate(Customer customer) throws ServiceException { + + LOGGER.debug("Creating Customer"); + + if(customer.getId()!=null && customer.getId()>0) { + super.update(customer); + } else { + + super.create(customer); + + } + } + + public void delete(Customer customer) throws ServiceException { + customer = getById(customer.getId()); + + //delete attributes + List attributes =customerAttributeService.getByCustomer(customer.getMerchantStore(), customer); + if(attributes!=null) { + for(CustomerAttribute attribute : attributes) { + customerAttributeService.delete(attribute); + } + } + customerRepository.delete(customer); + + } + + @Override + public Customer getByNick(String nick, String code) { + return customerRepository.findByNick(nick, code); + } + + @Override + public Customer getByPasswordResetToken(String storeCode, String token) { + return customerRepository.findByResetPasswordToken(token, storeCode); + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerAttributeService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerAttributeService.java new file mode 100755 index 0000000000..baa4725ead --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerAttributeService.java @@ -0,0 +1,31 @@ +package com.salesmanager.core.business.services.customer.attribute; + +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.customer.attribute.CustomerAttribute; +import com.salesmanager.core.model.merchant.MerchantStore; + + + +public interface CustomerAttributeService extends + SalesManagerEntityService { + + void saveOrUpdate(CustomerAttribute customerAttribute) + throws ServiceException; + + CustomerAttribute getByCustomerOptionId(MerchantStore store, + Long customerId, Long id); + + List getByCustomerOptionValueId(MerchantStore store, + Long id); + + List getByOptionId(MerchantStore store, Long id); + + + List getByCustomer(MerchantStore store, Customer customer); + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerAttributeServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerAttributeServiceImpl.java new file mode 100755 index 0000000000..8b8a89bfcb --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerAttributeServiceImpl.java @@ -0,0 +1,79 @@ +package com.salesmanager.core.business.services.customer.attribute; + +import java.util.List; + +import javax.inject.Inject; + +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.customer.attribute.CustomerAttributeRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.customer.attribute.CustomerAttribute; +import com.salesmanager.core.model.merchant.MerchantStore; + + + +@Service("customerAttributeService") +public class CustomerAttributeServiceImpl extends + SalesManagerEntityServiceImpl implements CustomerAttributeService { + + private CustomerAttributeRepository customerAttributeRepository; + + @Inject + public CustomerAttributeServiceImpl(CustomerAttributeRepository customerAttributeRepository) { + super(customerAttributeRepository); + this.customerAttributeRepository = customerAttributeRepository; + } + + + + + + @Override + public void saveOrUpdate(CustomerAttribute customerAttribute) + throws ServiceException { + + customerAttributeRepository.save(customerAttribute); + + + } + + @Override + public void delete(CustomerAttribute attribute) throws ServiceException { + + //override method, this allows the error that we try to remove a detached instance + attribute = this.getById(attribute.getId()); + super.delete(attribute); + + } + + + + @Override + public CustomerAttribute getByCustomerOptionId(MerchantStore store, Long customerId, Long id) { + return customerAttributeRepository.findByOptionId(store.getId(), customerId, id); + } + + + + @Override + public List getByCustomer(MerchantStore store, Customer customer) { + return customerAttributeRepository.findByCustomerId(store.getId(), customer.getId()); + } + + + @Override + public List getByCustomerOptionValueId(MerchantStore store, + Long id) { + return customerAttributeRepository.findByOptionValueId(store.getId(), id); + } + + @Override + public List getByOptionId(MerchantStore store, + Long id) { + return customerAttributeRepository.findByOptionId(store.getId(), id); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionService.java new file mode 100755 index 0000000000..aa8969d524 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionService.java @@ -0,0 +1,28 @@ +package com.salesmanager.core.business.services.customer.attribute; + +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.customer.attribute.CustomerOption; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + + +public interface CustomerOptionService extends SalesManagerEntityService { + + List listByStore(MerchantStore store, Language language) + throws ServiceException; + + + + void saveOrUpdate(CustomerOption entity) throws ServiceException; + + + + CustomerOption getByCode(MerchantStore store, String optionCode); + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionServiceImpl.java new file mode 100755 index 0000000000..0205b984df --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionServiceImpl.java @@ -0,0 +1,97 @@ +package com.salesmanager.core.business.services.customer.attribute; + +import java.util.List; + +import javax.inject.Inject; + +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.customer.attribute.CustomerOptionRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.customer.attribute.CustomerAttribute; +import com.salesmanager.core.model.customer.attribute.CustomerOption; +import com.salesmanager.core.model.customer.attribute.CustomerOptionSet; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + + + +@Service("customerOptionService") +public class CustomerOptionServiceImpl extends + SalesManagerEntityServiceImpl implements CustomerOptionService { + + + private CustomerOptionRepository customerOptionRepository; + + @Inject + private CustomerAttributeService customerAttributeService; + + @Inject + private CustomerOptionSetService customerOptionSetService; + + + @Inject + public CustomerOptionServiceImpl( + CustomerOptionRepository customerOptionRepository) { + super(customerOptionRepository); + this.customerOptionRepository = customerOptionRepository; + } + + @Override + public List listByStore(MerchantStore store, Language language) throws ServiceException { + + return customerOptionRepository.findByStore(store.getId(), language.getId()); + + } + + + @Override + public void saveOrUpdate(CustomerOption entity) throws ServiceException { + + + //save or update (persist and attach entities + if(entity.getId()!=null && entity.getId()>0) { + super.update(entity); + } else { + super.save(entity); + } + + } + + + @Override + public void delete(CustomerOption customerOption) throws ServiceException { + + //remove all attributes having this option + List attributes = customerAttributeService.getByOptionId(customerOption.getMerchantStore(), customerOption.getId()); + + for(CustomerAttribute attribute : attributes) { + customerAttributeService.delete(attribute); + } + + CustomerOption option = this.getById(customerOption.getId()); + + List optionSets = customerOptionSetService.listByOption(customerOption, customerOption.getMerchantStore()); + + for(CustomerOptionSet optionSet : optionSets) { + customerOptionSetService.delete(optionSet); + } + + //remove option + super.delete(option); + + } + + @Override + public CustomerOption getByCode(MerchantStore store, String optionCode) { + return customerOptionRepository.findByCode(store.getId(), optionCode); + } + + + + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionSetService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionSetService.java new file mode 100755 index 0000000000..df04cc9f2d --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionSetService.java @@ -0,0 +1,36 @@ +package com.salesmanager.core.business.services.customer.attribute; + +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.customer.attribute.CustomerOption; +import com.salesmanager.core.model.customer.attribute.CustomerOptionSet; +import com.salesmanager.core.model.customer.attribute.CustomerOptionValue; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + + +public interface CustomerOptionSetService extends SalesManagerEntityService { + + + + void saveOrUpdate(CustomerOptionSet entity) throws ServiceException; + + + + + List listByStore(MerchantStore store, + Language language) throws ServiceException; + + + + + List listByOption(CustomerOption option, + MerchantStore store) throws ServiceException; + + + List listByOptionValue(CustomerOptionValue optionValue, + MerchantStore store) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionSetServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionSetServiceImpl.java new file mode 100755 index 0000000000..06725ab8b1 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionSetServiceImpl.java @@ -0,0 +1,87 @@ +package com.salesmanager.core.business.services.customer.attribute; + +import java.util.List; + +import javax.inject.Inject; + +import org.apache.commons.lang3.Validate; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.customer.attribute.CustomerOptionSetRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.customer.attribute.CustomerOption; +import com.salesmanager.core.model.customer.attribute.CustomerOptionSet; +import com.salesmanager.core.model.customer.attribute.CustomerOptionValue; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + + + +@Service("customerOptionSetService") +public class CustomerOptionSetServiceImpl extends + SalesManagerEntityServiceImpl implements CustomerOptionSetService { + + + @Inject + private CustomerOptionSetRepository customerOptionSetRepository; + + + @Inject + public CustomerOptionSetServiceImpl( + CustomerOptionSetRepository customerOptionSetRepository) { + super(customerOptionSetRepository); + this.customerOptionSetRepository = customerOptionSetRepository; + } + + + @Override + public List listByOption(CustomerOption option, MerchantStore store) throws ServiceException { + Validate.notNull(store,"merchant store cannot be null"); + Validate.notNull(option,"option cannot be null"); + + return customerOptionSetRepository.findByOptionId(store.getId(), option.getId()); + } + + @Override + public void delete(CustomerOptionSet customerOptionSet) throws ServiceException { + customerOptionSet = customerOptionSetRepository.findOne(customerOptionSet.getId()); + super.delete(customerOptionSet); + } + + @Override + public List listByStore(MerchantStore store, Language language) throws ServiceException { + Validate.notNull(store,"merchant store cannot be null"); + + + return customerOptionSetRepository.findByStore(store.getId(),language.getId()); + } + + + @Override + public void saveOrUpdate(CustomerOptionSet entity) throws ServiceException { + Validate.notNull(entity,"customer option set cannot be null"); + + if(entity.getId()>0) { + super.update(entity); + } else { + super.create(entity); + } + + } + + + @Override + public List listByOptionValue( + CustomerOptionValue optionValue, MerchantStore store) + throws ServiceException { + return customerOptionSetRepository.findByOptionValueId(store.getId(), optionValue.getId()); + } + + + + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionValueService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionValueService.java new file mode 100755 index 0000000000..12b89b05e6 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionValueService.java @@ -0,0 +1,25 @@ +package com.salesmanager.core.business.services.customer.attribute; + +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.customer.attribute.CustomerOptionValue; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + + +public interface CustomerOptionValueService extends SalesManagerEntityService { + + + + List listByStore(MerchantStore store, Language language) + throws ServiceException; + + void saveOrUpdate(CustomerOptionValue entity) throws ServiceException; + + CustomerOptionValue getByCode(MerchantStore store, String optionValueCode); + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionValueServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionValueServiceImpl.java new file mode 100755 index 0000000000..14b0baf522 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/attribute/CustomerOptionValueServiceImpl.java @@ -0,0 +1,96 @@ +package com.salesmanager.core.business.services.customer.attribute; + +import java.util.List; + +import javax.inject.Inject; + +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.customer.attribute.CustomerOptionValueRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.customer.attribute.CustomerAttribute; +import com.salesmanager.core.model.customer.attribute.CustomerOptionSet; +import com.salesmanager.core.model.customer.attribute.CustomerOptionValue; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + + +@Service("customerOptionValueService") +public class CustomerOptionValueServiceImpl extends + SalesManagerEntityServiceImpl implements + CustomerOptionValueService { + + @Inject + private CustomerAttributeService customerAttributeService; + + private CustomerOptionValueRepository customerOptionValueRepository; + + @Inject + private CustomerOptionSetService customerOptionSetService; + + @Inject + public CustomerOptionValueServiceImpl( + CustomerOptionValueRepository customerOptionValueRepository) { + super(customerOptionValueRepository); + this.customerOptionValueRepository = customerOptionValueRepository; + } + + + @Override + public List listByStore(MerchantStore store, Language language) throws ServiceException { + + return customerOptionValueRepository.findByStore(store.getId(), language.getId()); + } + + + + + @Override + public void saveOrUpdate(CustomerOptionValue entity) throws ServiceException { + + + //save or update (persist and attach entities + if(entity.getId()!=null && entity.getId()>0) { + + super.update(entity); + + } else { + + super.save(entity); + + } + + } + + + public void delete(CustomerOptionValue customerOptionValue) throws ServiceException { + + //remove all attributes having this option + List attributes = customerAttributeService.getByCustomerOptionValueId(customerOptionValue.getMerchantStore(), customerOptionValue.getId()); + + for(CustomerAttribute attribute : attributes) { + customerAttributeService.delete(attribute); + } + + List optionSets = customerOptionSetService.listByOptionValue(customerOptionValue, customerOptionValue.getMerchantStore()); + + for(CustomerOptionSet optionSet : optionSets) { + customerOptionSetService.delete(optionSet); + } + + CustomerOptionValue option = super.getById(customerOptionValue.getId()); + + //remove option + super.delete(option); + + } + + @Override + public CustomerOptionValue getByCode(MerchantStore store, String optionValueCode) { + return customerOptionValueRepository.findByCode(store.getId(), optionValueCode); + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/customer/optin/CustomerOptinService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/optin/CustomerOptinService.java new file mode 100755 index 0000000000..fd49c63905 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/optin/CustomerOptinService.java @@ -0,0 +1,43 @@ +package com.salesmanager.core.business.services.customer.optin; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.system.optin.CustomerOptin; + +/** + * Used for optin in customers + * An implementation example is for signin in users + * @author carlsamson + * + */ +public interface CustomerOptinService extends SalesManagerEntityService { + + /** + * Optin a given customer. This has no reference to a specific Customer object but contains + * only email, first name and lastname + * @param optin + * @throws ServiceException + */ + void optinCumtomer(CustomerOptin optin) throws ServiceException; + + + /** + * Removes a specific CustomerOptin + * @param optin + * @throws ServiceException + */ + void optoutCumtomer(CustomerOptin optin) throws ServiceException; + + /** + * Find an existing CustomerOptin + * @param store + * @param emailAddress + * @param code + * @return + * @throws ServiceException + */ + CustomerOptin findByEmailAddress(MerchantStore store, String emailAddress, String code) throws ServiceException; + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/customer/optin/CustomerOptinServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/optin/CustomerOptinServiceImpl.java new file mode 100755 index 0000000000..68451e18f6 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/optin/CustomerOptinServiceImpl.java @@ -0,0 +1,52 @@ +package com.salesmanager.core.business.services.customer.optin; + + + +import javax.inject.Inject; + +import org.apache.commons.lang3.Validate; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.customer.optin.CustomerOptinRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.system.optin.CustomerOptin; + + +@Service +public class CustomerOptinServiceImpl extends SalesManagerEntityServiceImpl implements CustomerOptinService { + + + private CustomerOptinRepository customerOptinRepository; + + + @Inject + public CustomerOptinServiceImpl(CustomerOptinRepository customerOptinRepository) { + super(customerOptinRepository); + this.customerOptinRepository = customerOptinRepository; + } + + @Override + public void optinCumtomer(CustomerOptin optin) throws ServiceException { + Validate.notNull(optin,"CustomerOptin must not be null"); + + customerOptinRepository.save(optin); + + + } + + @Override + public void optoutCumtomer(CustomerOptin optin) throws ServiceException { + Validate.notNull(optin,"CustomerOptin must not be null"); + + customerOptinRepository.delete(optin); + + } + + @Override + public CustomerOptin findByEmailAddress(MerchantStore store, String emailAddress, String code) throws ServiceException { + return customerOptinRepository.findByMerchantAndCodeAndEmail(store.getId(), code, emailAddress); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/customer/review/CustomerReviewService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/review/CustomerReviewService.java new file mode 100755 index 0000000000..7b5f3eb55b --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/review/CustomerReviewService.java @@ -0,0 +1,34 @@ +package com.salesmanager.core.business.services.customer.review; + +import java.util.List; + +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.customer.review.CustomerReview; + +public interface CustomerReviewService extends + SalesManagerEntityService { + + /** + * All reviews created by a given customer + * @param customer + * @return + */ + List getByCustomer(Customer customer); + + /** + * All reviews received by a given customer + * @param customer + * @return + */ + List getByReviewedCustomer(Customer customer); + + /** + * Get a review made by a customer to another customer + * @param reviewer + * @param reviewed + * @return + */ + CustomerReview getByReviewerAndReviewed(Long reviewer, Long reviewed); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/customer/review/CustomerReviewServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/review/CustomerReviewServiceImpl.java new file mode 100755 index 0000000000..6f50e4a514 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/customer/review/CustomerReviewServiceImpl.java @@ -0,0 +1,109 @@ +package com.salesmanager.core.business.services.customer.review; + +import java.math.BigDecimal; +import java.util.List; + +import javax.inject.Inject; + +import org.apache.commons.lang3.Validate; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.customer.review.CustomerReviewRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.customer.review.CustomerReview; + +@Service("customerReviewService") +public class CustomerReviewServiceImpl extends + SalesManagerEntityServiceImpl implements CustomerReviewService { + + private CustomerReviewRepository customerReviewRepository; + + @Inject + private CustomerService customerService; + + @Inject + public CustomerReviewServiceImpl( + CustomerReviewRepository customerReviewRepository) { + super(customerReviewRepository); + this.customerReviewRepository = customerReviewRepository; + } + + + private void saveOrUpdate(CustomerReview review) throws ServiceException { + + + Validate.notNull(review,"CustomerReview cannot be null"); + Validate.notNull(review.getCustomer(),"CustomerReview.customer cannot be null"); + Validate.notNull(review.getReviewedCustomer(),"CustomerReview.reviewedCustomer cannot be null"); + + + //refresh customer + Customer customer = customerService.getById(review.getReviewedCustomer().getId()); + + //ajust product rating + Integer count = 0; + if(customer.getCustomerReviewCount()!=null) { + count = customer.getCustomerReviewCount(); + } + + + + + BigDecimal averageRating = customer.getCustomerReviewAvg(); + if(averageRating==null) { + averageRating = new BigDecimal(0); + } + //get reviews + + + BigDecimal totalRating = averageRating.multiply(new BigDecimal(count)); + totalRating = totalRating.add(new BigDecimal(review.getReviewRating())); + + count = count + 1; + double avg = totalRating.doubleValue() / count; + + customer.setCustomerReviewAvg(new BigDecimal(avg)); + customer.setCustomerReviewCount(count); + super.save(review); + + customerService.update(customer); + + review.setReviewedCustomer(customer); + + + } + + public void update(CustomerReview review) throws ServiceException { + this.saveOrUpdate(review); + } + + public void create(CustomerReview review) throws ServiceException { + this.saveOrUpdate(review); + } + + + + @Override + public List getByCustomer(Customer customer) { + Validate.notNull(customer,"Customer cannot be null"); + return customerReviewRepository.findByReviewer(customer.getId()); + } + + @Override + public List getByReviewedCustomer(Customer customer) { + Validate.notNull(customer,"Customer cannot be null"); + return customerReviewRepository.findByReviewed(customer.getId()); + } + + + @Override + public CustomerReview getByReviewerAndReviewed(Long reviewer, Long reviewed) { + Validate.notNull(reviewer,"Reviewer customer cannot be null"); + Validate.notNull(reviewed,"Reviewer customer cannot be null"); + return customerReviewRepository.findByRevieweAndReviewed(reviewer, reviewed); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/merchant/MerchantStoreService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/merchant/MerchantStoreService.java new file mode 100755 index 0000000000..3a4daa9ee3 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/merchant/MerchantStoreService.java @@ -0,0 +1,48 @@ +package com.salesmanager.core.business.services.merchant; + +import java.util.List; + +import java.util.Optional; +import org.springframework.data.domain.Page; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.common.GenericEntityList; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.merchant.MerchantStoreCriteria; + +public interface MerchantStoreService extends SalesManagerEntityService{ + + + MerchantStore getByCode(String code) throws ServiceException; + + MerchantStore getParent(String code) throws ServiceException; + + List findAllStoreNames() throws ServiceException; + + List findAllStoreNames(String code) throws ServiceException; + + List findAllStoreCodeNameEmail() throws ServiceException; + + Page listAll(Optional storeName, int page, int count) throws ServiceException; + + Page listByGroup(Optional storeName, String code, int page, int count) throws ServiceException; + + Page listAllRetailers(Optional storeName, int page, int count) throws ServiceException; + + Page listChildren(String code, int page, int count) throws ServiceException; + + boolean existByCode(String code); + + /** + * Is parent or child and part of a specific group + * @param code + * @return + */ + boolean isStoreInGroup(String code) throws ServiceException; + + void saveOrUpdate(MerchantStore store) throws ServiceException; + + GenericEntityList getByCriteria(MerchantStoreCriteria criteria) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/merchant/MerchantStoreServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/merchant/MerchantStoreServiceImpl.java new file mode 100755 index 0000000000..bb95d19a6c --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/merchant/MerchantStoreServiceImpl.java @@ -0,0 +1,176 @@ +package com.salesmanager.core.business.services.merchant; + +import java.util.List; +import java.util.Optional; + +import javax.inject.Inject; + +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.merchant.MerchantRepository; +import com.salesmanager.core.business.repositories.merchant.PageableMerchantRepository; +import com.salesmanager.core.business.services.catalog.product.type.ProductTypeService; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.common.GenericEntityList; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.merchant.MerchantStoreCriteria; + +@Service("merchantService") +public class MerchantStoreServiceImpl extends SalesManagerEntityServiceImpl + implements MerchantStoreService { + + @Inject + protected ProductTypeService productTypeService; + + @Autowired + private PageableMerchantRepository pageableMerchantRepository; + + private MerchantRepository merchantRepository; + + @Inject + public MerchantStoreServiceImpl(MerchantRepository merchantRepository) { + super(merchantRepository); + this.merchantRepository = merchantRepository; + } + + @Override + //@CacheEvict(value="store", key="#store.code") + public void saveOrUpdate(MerchantStore store) throws ServiceException { + super.save(store); + } + + @Override + /** + * cache moved in facades + */ + //@Cacheable(value = "store") + public MerchantStore getByCode(String code) throws ServiceException { + return merchantRepository.findByCode(code); + } + + @Override + public boolean existByCode(String code) { + return merchantRepository.existsByCode(code); + } + + @Override + public GenericEntityList getByCriteria(MerchantStoreCriteria criteria) throws ServiceException { + return merchantRepository.listByCriteria(criteria); + } + + @Override + public Page listChildren(String code, int page, int count) throws ServiceException { + Pageable pageRequest = PageRequest.of(page, count); + return pageableMerchantRepository.listByStore(code, pageRequest); + } + + @Override + public Page listAll(Optional storeName, int page, int count) throws ServiceException { + String store = null; + if (storeName != null && storeName.isPresent()) { + store = storeName.get(); + } + Pageable pageRequest = PageRequest.of(page, count); + return pageableMerchantRepository.listAll(store, pageRequest); + + } + + @Override + public List findAllStoreCodeNameEmail() throws ServiceException { + return merchantRepository.findAllStoreCodeNameEmail(); + } + + @Override + public Page listAllRetailers(Optional storeName, int page, int count) + throws ServiceException { + String store = null; + if (storeName != null && storeName.isPresent()) { + store = storeName.get(); + } + Pageable pageRequest = PageRequest.of(page, count); + return pageableMerchantRepository.listAllRetailers(store, pageRequest); + + } + + @Override + public List findAllStoreNames() throws ServiceException { + return merchantRepository.findAllStoreNames(); + } + + @Override + public MerchantStore getParent(String code) throws ServiceException { + Validate.notNull(code, "MerchantStore code cannot be null"); + + + //get it + MerchantStore storeModel = this.getByCode(code); + + if(storeModel == null) { + throw new ServiceException("Store with code [" + code + "] is not found"); + } + + if(storeModel.isRetailer() != null && storeModel.isRetailer() && storeModel.getParent() == null) { + return storeModel; + } + + if(storeModel.getParent() == null) { + return storeModel; + } + + return merchantRepository.getById(storeModel.getParent().getId()); + } + + + @Override + public List findAllStoreNames(String code) throws ServiceException { + return merchantRepository.findAllStoreNames(code); + } + + /** + * Store might be alone (known as retailer) + * A retailer can have multiple child attached + * + * This method from a store code is able to retrieve parent and childs. + * Method can also filter on storeName + */ + @Override + public Page listByGroup(Optional storeName, String code, int page, int count) throws ServiceException { + + String name = null; + if (storeName != null && storeName.isPresent()) { + name = storeName.get(); + } + + + MerchantStore store = getByCode(code);//if exist + Optional id = Optional.ofNullable(store.getId()); + + + Pageable pageRequest = PageRequest.of(page, count); + + + return pageableMerchantRepository.listByGroup(code, id.get(), name, pageRequest); + + + } + + @Override + public boolean isStoreInGroup(String code) throws ServiceException{ + + MerchantStore store = getByCode(code);//if exist + Optional id = Optional.ofNullable(store.getId()); + + List stores = merchantRepository.listByGroup(code, id.get()); + + + return stores.size() > 0; + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/order/OrderService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/order/OrderService.java new file mode 100755 index 0000000000..4a076e371f --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/order/OrderService.java @@ -0,0 +1,130 @@ +package com.salesmanager.core.business.services.order; + +import java.io.ByteArrayOutputStream; +import java.util.Date; +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.order.OrderCriteria; +import com.salesmanager.core.model.order.OrderList; +import com.salesmanager.core.model.order.OrderSummary; +import com.salesmanager.core.model.order.OrderTotalSummary; +import com.salesmanager.core.model.order.orderstatus.OrderStatusHistory; +import com.salesmanager.core.model.payments.Payment; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; + + + +public interface OrderService extends SalesManagerEntityService { + + void addOrderStatusHistory(Order order, OrderStatusHistory history) + throws ServiceException; + + /** + * Can be used to calculates the final prices of all items contained in checkout page + * @param orderSummary + * @param customer + * @param store + * @param language + * @return + * @throws ServiceException + */ + OrderTotalSummary caculateOrderTotal(OrderSummary orderSummary, + Customer customer, MerchantStore store, Language language) + throws ServiceException; + + /** + * Can be used to calculates the final prices of all items contained in a ShoppingCart + * @param orderSummary + * @param store + * @param language + * @return + * @throws ServiceException + */ + OrderTotalSummary caculateOrderTotal(OrderSummary orderSummary, + MerchantStore store, Language language) throws ServiceException; + + + /** + * Can be used to calculates the final prices of all items contained in checkout page + * @param shoppingCart + * @param customer + * @param store + * @param language + * @return @return {@link OrderTotalSummary} + * @throws ServiceException + */ + OrderTotalSummary calculateShoppingCartTotal(final ShoppingCart shoppingCart,final Customer customer, final MerchantStore store, final Language language) throws ServiceException; + + /** + * Can be used to calculates the final prices of all items contained in a ShoppingCart + * @param shoppingCart + * @param store + * @param language + * @return {@link OrderTotalSummary} + * @throws ServiceException + */ + OrderTotalSummary calculateShoppingCartTotal(final ShoppingCart shoppingCart,final MerchantStore store, final Language language) throws ServiceException; + + ByteArrayOutputStream generateInvoice(MerchantStore store, Order order, + Language language) throws ServiceException; + + Order getOrder(Long id, MerchantStore store); + + + /** + * For finding orders. Mainly used in the administration tool + * @param store + * @param criteria + * @return + */ + OrderList listByStore(MerchantStore store, OrderCriteria criteria); + + + /** + * get all orders. Mainly used in the administration tool + * @param criteria + * @return + */ + OrderList getOrders(OrderCriteria criteria, MerchantStore store); + + void saveOrUpdate(Order order) throws ServiceException; + + Order processOrder(Order order, Customer customer, + List items, OrderTotalSummary summary, + Payment payment, MerchantStore store) throws ServiceException; + + Order processOrder(Order order, Customer customer, + List items, OrderTotalSummary summary, + Payment payment, Transaction transaction, MerchantStore store) + throws ServiceException; + + + + + /** + * Determines if an Order has download files + * @param order + * @return + * @throws ServiceException + */ + boolean hasDownloadFiles(Order order) throws ServiceException; + + /** + * List all orders that have been pre-authorized but not captured + * @param store + * @param startDate + * @param endDate + * @return + * @throws ServiceException + */ + List getCapturableOrders(MerchantStore store, Date startDate, Date endDate) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/order/OrderServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/order/OrderServiceImpl.java new file mode 100755 index 0000000000..b6bac5202f --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/order/OrderServiceImpl.java @@ -0,0 +1,680 @@ +package com.salesmanager.core.business.services.order; + +import java.io.ByteArrayOutputStream; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.order.InvoiceModule; +import com.salesmanager.core.business.repositories.order.OrderRepository; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.order.ordertotal.OrderTotalService; +import com.salesmanager.core.business.services.payments.PaymentService; +import com.salesmanager.core.business.services.payments.TransactionService; +import com.salesmanager.core.business.services.shipping.ShippingService; +import com.salesmanager.core.business.services.shoppingcart.ShoppingCartService; +import com.salesmanager.core.business.services.tax.TaxService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.common.UserContext; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.order.OrderCriteria; +import com.salesmanager.core.model.order.OrderList; +import com.salesmanager.core.model.order.OrderSummary; +import com.salesmanager.core.model.order.OrderSummaryType; +import com.salesmanager.core.model.order.OrderTotal; +import com.salesmanager.core.model.order.OrderTotalSummary; +import com.salesmanager.core.model.order.OrderTotalType; +import com.salesmanager.core.model.order.OrderTotalVariation; +import com.salesmanager.core.model.order.OrderValueType; +import com.salesmanager.core.model.order.orderproduct.OrderProduct; +import com.salesmanager.core.model.order.orderstatus.OrderStatus; +import com.salesmanager.core.model.order.orderstatus.OrderStatusHistory; +import com.salesmanager.core.model.payments.Payment; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.payments.TransactionType; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shipping.ShippingConfiguration; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.model.tax.TaxItem; + +@Service("orderService") +public class OrderServiceImpl extends SalesManagerEntityServiceImpl implements OrderService { + + private static final Logger LOGGER = LoggerFactory.getLogger(OrderServiceImpl.class); + + @Inject + private InvoiceModule invoiceModule; + + @Inject + private ShippingService shippingService; + + @Inject + private PaymentService paymentService; + + @Inject + private ProductService productService; + + @Inject + private TaxService taxService; + + @Inject + private CustomerService customerService; + + @Inject + private ShoppingCartService shoppingCartService; + + @Inject + private TransactionService transactionService; + + @Inject + private OrderTotalService orderTotalService; + + private final OrderRepository orderRepository; + + @Inject + public OrderServiceImpl(OrderRepository orderRepository) { + super(orderRepository); + this.orderRepository = orderRepository; + } + + @Override + public void addOrderStatusHistory(Order order, OrderStatusHistory history) throws ServiceException { + order.getOrderHistory().add(history); + history.setOrder(order); + update(order); + } + + @Override + public Order processOrder(Order order, Customer customer, List items, OrderTotalSummary summary, Payment payment, MerchantStore store) throws ServiceException { + + return process(order, customer, items, summary, payment, null, store); + } + + @Override + public Order processOrder(Order order, Customer customer, List items, OrderTotalSummary summary, Payment payment, Transaction transaction, MerchantStore store) throws ServiceException { + return process(order, customer, items, summary, payment, transaction, store); + } + + private Order process(Order order, Customer customer, List items, OrderTotalSummary summary, Payment payment, Transaction transaction, MerchantStore store) throws ServiceException { + + + Validate.notNull(order, "Order cannot be null"); + Validate.notNull(customer, "Customer cannot be null (even if anonymous order)"); + Validate.notEmpty(items, "ShoppingCart items cannot be null"); + Validate.notNull(payment, "Payment cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(summary, "Order total Summary cannot be null"); + + UserContext context = UserContext.getCurrentInstance(); + if(context != null) { + String ipAddress = context.getIpAddress(); + if(!StringUtils.isBlank(ipAddress)) { + order.setIpAddress(ipAddress); + } + } + + + //first process payment + Transaction processTransaction = paymentService.processPayment(customer, store, payment, items, order); + + if(order.getOrderHistory()==null || order.getOrderHistory().size()==0 || order.getStatus()==null) { + OrderStatus status = order.getStatus(); + if(status==null) { + status = OrderStatus.ORDERED; + order.setStatus(status); + } + Set statusHistorySet = new HashSet(); + OrderStatusHistory statusHistory = new OrderStatusHistory(); + statusHistory.setStatus(status); + statusHistory.setDateAdded(new Date()); + statusHistory.setOrder(order); + statusHistorySet.add(statusHistory); + order.setOrderHistory(statusHistorySet); + + } + + if(customer.getId()==null || customer.getId()==0) { + customerService.create(customer); + } + + order.setCustomerId(customer.getId()); + this.create(order); + + if(transaction!=null) { + transaction.setOrder(order); + if(transaction.getId()==null || transaction.getId()==0) { + transactionService.create(transaction); + } else { + transactionService.update(transaction); + } + } + + if(processTransaction!=null) { + processTransaction.setOrder(order); + if(processTransaction.getId()==null || processTransaction.getId()==0) { + transactionService.create(processTransaction); + } else { + transactionService.update(processTransaction); + } + } + + /** + * decrement inventory + */ + LOGGER.debug( "Update inventory" ); + Set products = order.getOrderProducts(); + for(OrderProduct orderProduct : products) { + orderProduct.getProductQuantity(); + Product p = productService.getById(orderProduct.getId()); + if(p == null) + throw new ServiceException(ServiceException.EXCEPTION_INVENTORY_MISMATCH); + for(ProductAvailability availability : p.getAvailabilities()) { + int qty = availability.getProductQuantity(); + if(qty < orderProduct.getProductQuantity()) { + //throw new ServiceException(ServiceException.EXCEPTION_INVENTORY_MISMATCH); + LOGGER.error("APP-BACKEND [" + ServiceException.EXCEPTION_INVENTORY_MISMATCH + "]"); + } + qty = qty - orderProduct.getProductQuantity(); + availability.setProductQuantity(qty); + } + productService.update(p); + } + + + + return order; + } + + private OrderTotalSummary caculateOrder(OrderSummary summary, Customer customer, final MerchantStore store, final Language language) throws Exception { + + OrderTotalSummary totalSummary = new OrderTotalSummary(); + List orderTotals = new ArrayList(); + Map otherPricesTotals = new HashMap(); + + ShippingConfiguration shippingConfiguration = null; + + BigDecimal grandTotal = new BigDecimal(0); + grandTotal.setScale(2, RoundingMode.HALF_UP); + + //price by item + /** + * qty * price + * subtotal + */ + BigDecimal subTotal = new BigDecimal(0); + subTotal.setScale(2, RoundingMode.HALF_UP); + for(ShoppingCartItem item : summary.getProducts()) { + + BigDecimal st = item.getItemPrice().multiply(new BigDecimal(item.getQuantity())); + item.setSubTotal(st); + subTotal = subTotal.add(st); + //Other prices + FinalPrice finalPrice = item.getFinalPrice(); + if(finalPrice!=null) { + List otherPrices = finalPrice.getAdditionalPrices(); + if(otherPrices!=null) { + for(FinalPrice price : otherPrices) { + if(!price.isDefaultPrice()) { + OrderTotal itemSubTotal = otherPricesTotals.get(price.getProductPrice().getCode()); + + if(itemSubTotal==null) { + itemSubTotal = new OrderTotal(); + itemSubTotal.setModule(Constants.OT_ITEM_PRICE_MODULE_CODE); + itemSubTotal.setTitle(Constants.OT_ITEM_PRICE_MODULE_CODE); + itemSubTotal.setOrderTotalCode(price.getProductPrice().getCode()); + itemSubTotal.setOrderTotalType(OrderTotalType.PRODUCT); + itemSubTotal.setSortOrder(0); + otherPricesTotals.put(price.getProductPrice().getCode(), itemSubTotal); + } + + BigDecimal orderTotalValue = itemSubTotal.getValue(); + if(orderTotalValue==null) { + orderTotalValue = new BigDecimal(0); + orderTotalValue.setScale(2, RoundingMode.HALF_UP); + } + + orderTotalValue = orderTotalValue.add(price.getFinalPrice()); + itemSubTotal.setValue(orderTotalValue); + if(price.getProductPrice().getProductPriceType().name().equals(OrderValueType.ONE_TIME)) { + subTotal = subTotal.add(price.getFinalPrice()); + } + } + } + } + } + } + + //only in order page, otherwise invokes too many processing + if( + OrderSummaryType.ORDERTOTAL.name().equals(summary.getOrderSummaryType().name()) || + OrderSummaryType.SHOPPINGCART.name().equals(summary.getOrderSummaryType().name()) + + ) { + + //Post processing order total variation modules for sub total calculation - drools, custom modules + //may affect the sub total + OrderTotalVariation orderTotalVariation = orderTotalService.findOrderTotalVariation(summary, customer, store, language); + + int currentCount = 10; + + if(CollectionUtils.isNotEmpty(orderTotalVariation.getVariations())) { + for(OrderTotal variation : orderTotalVariation.getVariations()) { + variation.setSortOrder(currentCount++); + orderTotals.add(variation); + subTotal = subTotal.subtract(variation.getValue()); + } + } + + } + + + totalSummary.setSubTotal(subTotal); + grandTotal=grandTotal.add(subTotal); + + OrderTotal orderTotalSubTotal = new OrderTotal(); + orderTotalSubTotal.setModule(Constants.OT_SUBTOTAL_MODULE_CODE); + orderTotalSubTotal.setOrderTotalType(OrderTotalType.SUBTOTAL); + orderTotalSubTotal.setOrderTotalCode("order.total.subtotal"); + orderTotalSubTotal.setTitle(Constants.OT_SUBTOTAL_MODULE_CODE); + orderTotalSubTotal.setSortOrder(5); + orderTotalSubTotal.setValue(subTotal); + + orderTotals.add(orderTotalSubTotal); + + + //shipping + if(summary.getShippingSummary()!=null) { + + + OrderTotal shippingSubTotal = new OrderTotal(); + shippingSubTotal.setModule(Constants.OT_SHIPPING_MODULE_CODE); + shippingSubTotal.setOrderTotalType(OrderTotalType.SHIPPING); + shippingSubTotal.setOrderTotalCode("order.total.shipping"); + shippingSubTotal.setTitle(Constants.OT_SHIPPING_MODULE_CODE); + shippingSubTotal.setSortOrder(100); + + orderTotals.add(shippingSubTotal); + + if(!summary.getShippingSummary().isFreeShipping()) { + shippingSubTotal.setValue(summary.getShippingSummary().getShipping()); + grandTotal=grandTotal.add(summary.getShippingSummary().getShipping()); + } else { + shippingSubTotal.setValue(new BigDecimal(0)); + grandTotal=grandTotal.add(new BigDecimal(0)); + } + + //check handling fees + shippingConfiguration = shippingService.getShippingConfiguration(store); + if(summary.getShippingSummary().getHandling()!=null && summary.getShippingSummary().getHandling().doubleValue()>0) { + if(shippingConfiguration.getHandlingFees()!=null && shippingConfiguration.getHandlingFees().doubleValue()>0) { + OrderTotal handlingubTotal = new OrderTotal(); + handlingubTotal.setModule(Constants.OT_HANDLING_MODULE_CODE); + handlingubTotal.setOrderTotalType(OrderTotalType.HANDLING); + handlingubTotal.setOrderTotalCode("order.total.handling"); + handlingubTotal.setTitle(Constants.OT_HANDLING_MODULE_CODE); + //handlingubTotal.setText("order.total.handling"); + handlingubTotal.setSortOrder(120); + handlingubTotal.setValue(summary.getShippingSummary().getHandling()); + orderTotals.add(handlingubTotal); + grandTotal=grandTotal.add(summary.getShippingSummary().getHandling()); + } + } + } + + //tax + List taxes = taxService.calculateTax(summary, customer, store, language); + if(taxes!=null && taxes.size()>0) { + BigDecimal totalTaxes = new BigDecimal(0); + totalTaxes.setScale(2, RoundingMode.HALF_UP); + int taxCount = 200; + for(TaxItem tax : taxes) { + + OrderTotal taxLine = new OrderTotal(); + taxLine.setModule(Constants.OT_TAX_MODULE_CODE); + taxLine.setOrderTotalType(OrderTotalType.TAX); + taxLine.setOrderTotalCode(tax.getLabel()); + taxLine.setSortOrder(taxCount); + taxLine.setTitle(Constants.OT_TAX_MODULE_CODE); + taxLine.setText(tax.getLabel()); + taxLine.setValue(tax.getItemPrice()); + + totalTaxes = totalTaxes.add(tax.getItemPrice()); + orderTotals.add(taxLine); + //grandTotal=grandTotal.add(tax.getItemPrice()); + + taxCount ++; + + } + grandTotal = grandTotal.add(totalTaxes); + totalSummary.setTaxTotal(totalTaxes); + } + + // grand total + OrderTotal orderTotal = new OrderTotal(); + orderTotal.setModule(Constants.OT_TOTAL_MODULE_CODE); + orderTotal.setOrderTotalType(OrderTotalType.TOTAL); + orderTotal.setOrderTotalCode("order.total.total"); + orderTotal.setTitle(Constants.OT_TOTAL_MODULE_CODE); + //orderTotal.setText("order.total.total"); + orderTotal.setSortOrder(500); + orderTotal.setValue(grandTotal); + orderTotals.add(orderTotal); + + totalSummary.setTotal(grandTotal); + totalSummary.setTotals(orderTotals); + return totalSummary; + + } + + + @Override + public OrderTotalSummary caculateOrderTotal(final OrderSummary orderSummary, final Customer customer, final MerchantStore store, final Language language) throws ServiceException { + Validate.notNull(orderSummary,"Order summary cannot be null"); + Validate.notNull(orderSummary.getProducts(),"Order summary.products cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null"); + Validate.notNull(customer,"Customer cannot be null"); + + try { + return caculateOrder(orderSummary, customer, store, language); + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + + + @Override + public OrderTotalSummary caculateOrderTotal(final OrderSummary orderSummary, final MerchantStore store, final Language language) throws ServiceException { + Validate.notNull(orderSummary,"Order summary cannot be null"); + Validate.notNull(orderSummary.getProducts(),"Order summary.products cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null"); + + try { + return caculateOrder(orderSummary, null, store, language); + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + private OrderTotalSummary caculateShoppingCart( ShoppingCart shoppingCart, final Customer customer, final MerchantStore store, final Language language) throws Exception { + + + OrderSummary orderSummary = new OrderSummary(); + orderSummary.setOrderSummaryType(OrderSummaryType.SHOPPINGCART); + + if(!StringUtils.isBlank(shoppingCart.getPromoCode())) { + Date promoDateAdded = shoppingCart.getPromoAdded();//promo valid 1 day + if(promoDateAdded == null) { + promoDateAdded = new Date(); + } + Instant instant = promoDateAdded.toInstant(); + ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault()); + LocalDate date = zdt.toLocalDate(); + //date added < date + 1 day + LocalDate tomorrow = LocalDate.now().plusDays(1); + if(date.isBefore(tomorrow)) { + orderSummary.setPromoCode(shoppingCart.getPromoCode()); + } else { + //clear promo + shoppingCart.setPromoCode(null); + shoppingCartService.saveOrUpdate(shoppingCart); + } + } + + List itemList = new ArrayList(shoppingCart.getLineItems()); + //filter out unavailable + itemList = itemList.stream().filter(p -> p.getProduct().isAvailable()).collect(Collectors.toList()); + orderSummary.setProducts(itemList); + + + return caculateOrder(orderSummary, customer, store, language); + + } + + + /** + *

    Method will be used to calculate Shopping cart total as well will update price for each + * line items. + *

    + * @param shoppingCart + * @param customer + * @param store + * @param language + * @return {@link OrderTotalSummary} + * @throws ServiceException + * + */ + @Override + public OrderTotalSummary calculateShoppingCartTotal( + final ShoppingCart shoppingCart, final Customer customer, final MerchantStore store, + final Language language) throws ServiceException { + Validate.notNull(shoppingCart,"Order summary cannot be null"); + Validate.notNull(customer,"Customery cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null."); + try { + return caculateShoppingCart(shoppingCart, customer, store, language); + } catch (Exception e) { + LOGGER.error( "Error while calculating shopping cart total" +e ); + throw new ServiceException(e); + } + + } + + + + + /** + *

    Method will be used to calculate Shopping cart total as well will update price for each + * line items. + *

    + * @param shoppingCart + * @param store + * @param language + * @return {@link OrderTotalSummary} + * @throws ServiceException + * + */ + @Override + public OrderTotalSummary calculateShoppingCartTotal( + final ShoppingCart shoppingCart, final MerchantStore store, final Language language) + throws ServiceException { + Validate.notNull(shoppingCart,"Order summary cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null"); + + try { + return caculateShoppingCart(shoppingCart, null, store, language); + } catch (Exception e) { + LOGGER.error( "Error while calculating shopping cart total" +e ); + throw new ServiceException(e); + } + } + + @Override + public void delete(final Order order) throws ServiceException { + + + super.delete(order); + } + + + @Override + public ByteArrayOutputStream generateInvoice(final MerchantStore store, final Order order, final Language language) throws ServiceException { + + Validate.notNull(order.getOrderProducts(),"Order products cannot be null"); + Validate.notNull(order.getOrderTotal(),"Order totals cannot be null"); + + try { + return invoiceModule.createInvoice(store, order, language); + } catch(Exception e) { + throw new ServiceException(e); + } + + + + } + + @Override + public Order getOrder(final Long orderId, MerchantStore store ) { + Validate.notNull(orderId, "Order id cannot be null"); + Validate.notNull(store, "Store cannot be null"); + return orderRepository.findOne(orderId, store.getId()); + } + + + /** legacy **/ + @Override + public OrderList listByStore(final MerchantStore store, final OrderCriteria criteria) { + return orderRepository.listByStore(store, criteria); + } + + @Override + public OrderList getOrders(final OrderCriteria criteria, MerchantStore store) { + return orderRepository.listOrders(store, criteria); + } + + + @Override + public void saveOrUpdate(final Order order) throws ServiceException { + + if(order.getId()!=null && order.getId()>0) { + LOGGER.debug("Updating Order"); + super.update(order); + + } else { + LOGGER.debug("Creating Order"); + super.create(order); + + } + } + + @Override + public boolean hasDownloadFiles(Order order) throws ServiceException { + + Validate.notNull(order,"Order cannot be null"); + Validate.notNull(order.getOrderProducts(),"Order products cannot be null"); + Validate.notEmpty(order.getOrderProducts(),"Order products cannot be empty"); + + boolean hasDownloads = false; + for(OrderProduct orderProduct : order.getOrderProducts()) { + + if(CollectionUtils.isNotEmpty(orderProduct.getDownloads())) { + hasDownloads = true; + break; + } + } + + return hasDownloads; + } + + @Override + public List getCapturableOrders(MerchantStore store, Date startDate, Date endDate) throws ServiceException { + + List transactions = transactionService.listTransactions(startDate, endDate); + + List returnOrders = null; + + if(!CollectionUtils.isEmpty(transactions)) { + + returnOrders = new ArrayList(); + + //order id + Map preAuthOrders = new HashMap (); + //order id + Map> processingTransactions = new HashMap> (); + + for(Transaction trx : transactions) { + Order order = trx.getOrder(); + if(TransactionType.AUTHORIZE.name().equals(trx.getTransactionType().name())) { + preAuthOrders.put(order.getId(), order); + } + + //put transaction + List listTransactions = null; + if(processingTransactions.containsKey(order.getId())) { + listTransactions = processingTransactions.get(order.getId()); + } else { + listTransactions = new ArrayList(); + processingTransactions.put(order.getId(), listTransactions); + } + listTransactions.add(trx); + } + + //should have when captured + /** + * Order id Transaction type + * 1 AUTHORIZE + * 1 CAPTURE + */ + + //should have when not captured + /** + * Order id Transaction type + * 2 AUTHORIZE + */ + + for(Long orderId : processingTransactions.keySet()) { + + List trx = processingTransactions.get(orderId); + if(CollectionUtils.isNotEmpty(trx)) { + + boolean capturable = true; + for(Transaction t : trx) { + + if(TransactionType.CAPTURE.name().equals(t.getTransactionType().name())) { + capturable = false; + } else if(TransactionType.AUTHORIZECAPTURE.name().equals(t.getTransactionType().name())) { + capturable = false; + } else if(TransactionType.REFUND.name().equals(t.getTransactionType().name())) { + capturable = false; + } + + } + + if(capturable) { + Order o = preAuthOrders.get(orderId); + returnOrders.add(o); + } + + } + + + } + } + + return returnOrders; + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/order/orderproduct/OrderProductDownloadService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/order/orderproduct/OrderProductDownloadService.java new file mode 100755 index 0000000000..3914fbd621 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/order/orderproduct/OrderProductDownloadService.java @@ -0,0 +1,18 @@ +package com.salesmanager.core.business.services.order.orderproduct; + +import java.util.List; + +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.order.orderproduct.OrderProductDownload; + + +public interface OrderProductDownloadService extends SalesManagerEntityService { + + /** + * List {@link OrderProductDownload} by order id + * @param orderId + * @return + */ + List getByOrderId(Long orderId); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/order/orderproduct/OrderProductDownloadServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/order/orderproduct/OrderProductDownloadServiceImpl.java new file mode 100755 index 0000000000..f51d49ebf2 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/order/orderproduct/OrderProductDownloadServiceImpl.java @@ -0,0 +1,38 @@ +package com.salesmanager.core.business.services.order.orderproduct; + +import java.util.List; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.repositories.order.orderproduct.OrderProductDownloadRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.order.orderproduct.OrderProductDownload; + + + + +@Service("orderProductDownloadService") +public class OrderProductDownloadServiceImpl extends SalesManagerEntityServiceImpl implements OrderProductDownloadService { + + private static final Logger LOGGER = LoggerFactory.getLogger(OrderProductDownloadServiceImpl.class); + + + private final OrderProductDownloadRepository orderProductDownloadRepository; + + @Inject + public OrderProductDownloadServiceImpl(OrderProductDownloadRepository orderProductDownloadRepository) { + super(orderProductDownloadRepository); + this.orderProductDownloadRepository = orderProductDownloadRepository; + } + + @Override + public List getByOrderId(Long orderId) { + return orderProductDownloadRepository.findByOrderId(orderId); + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/order/orderstatushistory/OrderStatusHistoryService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/order/orderstatushistory/OrderStatusHistoryService.java new file mode 100644 index 0000000000..c00b0cbe86 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/order/orderstatushistory/OrderStatusHistoryService.java @@ -0,0 +1,10 @@ +package com.salesmanager.core.business.services.order.orderstatushistory; + +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.order.orderstatus.OrderStatusHistory; + +import java.util.List; + +public interface OrderStatusHistoryService { + List findByOrder(Order order); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/order/orderstatushistory/OrderStatusHistoryServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/order/orderstatushistory/OrderStatusHistoryServiceImpl.java new file mode 100644 index 0000000000..f01ea8968a --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/order/orderstatushistory/OrderStatusHistoryServiceImpl.java @@ -0,0 +1,20 @@ +package com.salesmanager.core.business.services.order.orderstatushistory; + +import com.salesmanager.core.business.repositories.order.OrderStatusHistoryRepository; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.order.orderstatus.OrderStatusHistory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class OrderStatusHistoryServiceImpl implements OrderStatusHistoryService{ + @Autowired + private OrderStatusHistoryRepository orderStatusHistoryRepository; + + @Override + public List findByOrder(Order order) { + return orderStatusHistoryRepository.findByOrderId(order.getId()); + } +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/order/ordertotal/OrderTotalService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/order/ordertotal/OrderTotalService.java new file mode 100755 index 0000000000..0a628af087 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/order/ordertotal/OrderTotalService.java @@ -0,0 +1,19 @@ +package com.salesmanager.core.business.services.order.ordertotal; + +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.OrderSummary; +import com.salesmanager.core.model.order.OrderTotalVariation; +import com.salesmanager.core.model.reference.language.Language; + +/** + * Additional dynamic order total calculation + * from the rules engine and other modules + * @author carlsamson + * + */ +public interface OrderTotalService { + + OrderTotalVariation findOrderTotalVariation(final OrderSummary summary, final Customer customer, final MerchantStore store, final Language language) throws Exception; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/order/ordertotal/OrderTotalServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/order/ordertotal/OrderTotalServiceImpl.java new file mode 100755 index 0000000000..874a65e406 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/order/ordertotal/OrderTotalServiceImpl.java @@ -0,0 +1,74 @@ +package com.salesmanager.core.business.services.order.ordertotal; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Resource; +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.OrderSummary; +import com.salesmanager.core.model.order.OrderTotal; +import com.salesmanager.core.model.order.OrderTotalVariation; +import com.salesmanager.core.model.order.RebatesOrderTotalVariation; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.modules.order.total.OrderTotalPostProcessorModule; + +@Service("OrderTotalService") +public class OrderTotalServiceImpl implements OrderTotalService { + + @Autowired + @Resource(name="orderTotalsPostProcessors") + List orderTotalPostProcessors; + + @Inject + private ProductService productService; + + + @Override + public OrderTotalVariation findOrderTotalVariation(OrderSummary summary, Customer customer, MerchantStore store, Language language) + throws Exception { + + RebatesOrderTotalVariation variation = new RebatesOrderTotalVariation(); + + List totals = null; + + if(orderTotalPostProcessors != null) { + for(OrderTotalPostProcessorModule module : orderTotalPostProcessors) { + //TODO check if the module is enabled from the Admin + + List items = summary.getProducts(); + for(ShoppingCartItem item : items) { + + Product product = productService.getBySku(item.getSku(), store, language); + //Product product = productService.getProductForLocale(productId, language, languageService.toLocale(language, store)); + + OrderTotal orderTotal = module.caculateProductPiceVariation(summary, item, product, customer, store); + if(orderTotal==null) { + continue; + } + if(totals==null) { + totals = new ArrayList(); + variation.setVariations(totals); + } + + //if product is null it will be catched when invoking the module + orderTotal.setText(StringUtils.isNoneBlank(orderTotal.getText())?orderTotal.getText():product.getProductDescription().getName()); + variation.getVariations().add(orderTotal); + } + } + } + + + return variation; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/payments/PaymentService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/payments/PaymentService.java new file mode 100755 index 0000000000..58739b17d9 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/payments/PaymentService.java @@ -0,0 +1,121 @@ +package com.salesmanager.core.business.services.payments; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.payments.CreditCardType; +import com.salesmanager.core.model.payments.Payment; +import com.salesmanager.core.model.payments.PaymentMethod; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.modules.integration.payment.model.PaymentModule; + +public interface PaymentService { + + List getPaymentMethods(MerchantStore store) + throws ServiceException; + + Map getPaymentModulesConfigured( + MerchantStore store) throws ServiceException; + + Transaction processPayment(Customer customer, MerchantStore store, Payment payment, List items, Order order) throws ServiceException; + Transaction processRefund(Order order, Customer customer, MerchantStore store, BigDecimal amount) throws ServiceException; + + /** + * Get a specific Payment module by payment type CREDITCART, MONEYORDER ... + * @param store + * @param type (payment type) + * @return IntegrationModule + * @throws ServiceException + */ + IntegrationModule getPaymentMethodByType(MerchantStore store, String type) + throws ServiceException; + + /** + * Get a specific Payment module by payment code (defined in integrationmoduel.json) paypal, authorizenet .. + * @param store + * @param name + * @return IntegrationModule + * @throws ServiceException + */ + IntegrationModule getPaymentMethodByCode(MerchantStore store, String name) + throws ServiceException; + + /** + * Saves a payment module configuration + * @param configuration + * @param store + * @throws ServiceException + */ + void savePaymentModuleConfiguration(IntegrationConfiguration configuration, + MerchantStore store) throws ServiceException; + + /** + * Validates if the credit card input information are correct + * @param number + * @param type + * @param month + * @param date + * @throws ServiceException + */ + void validateCreditCard(String number, CreditCardType creditCard, String month, String date) + throws ServiceException; + + /** + * Get the integration configuration + * for a specific payment module + * @param moduleCode + * @param store + * @return IntegrationConfiguration + * @throws ServiceException + */ + IntegrationConfiguration getPaymentConfiguration(String moduleCode, + MerchantStore store) throws ServiceException; + + void removePaymentModuleConfiguration(String moduleCode, MerchantStore store) + throws ServiceException; + + Transaction processCapturePayment(Order order, Customer customer, + MerchantStore store) + throws ServiceException; + + /** + * Initializes a transaction + * @param order + * @param customer + * @param payment + * @param store + * @return Transaction + */ + Transaction initTransaction(Order order, Customer customer, Payment payment, MerchantStore store) throws ServiceException; + + /** + * Initializes a transaction without an order + * @param order + * @param customer + * @param payment + * @param store + * @return Transaction + */ + Transaction initTransaction(Customer customer, Payment payment, MerchantStore store) throws ServiceException; + + List getAcceptedPaymentMethods(MerchantStore store) + throws ServiceException; + + /** + * Returns a PaymentModule based on the payment code + * @param paymentModuleCode + * @return PaymentModule + * @throws ServiceException + */ + PaymentModule getPaymentModule(String paymentModuleCode) + throws ServiceException; + +} \ No newline at end of file diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/payments/PaymentServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/payments/PaymentServiceImpl.java new file mode 100755 index 0000000000..6b25968b71 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/payments/PaymentServiceImpl.java @@ -0,0 +1,784 @@ +package com.salesmanager.core.business.services.payments; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.annotation.Resource; +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.order.OrderService; +import com.salesmanager.core.business.services.reference.loader.ConfigurationModulesLoader; +import com.salesmanager.core.business.services.system.MerchantConfigurationService; +import com.salesmanager.core.business.services.system.ModuleConfigurationService; +import com.salesmanager.core.business.utils.CoreConfiguration; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.order.OrderTotal; +import com.salesmanager.core.model.order.OrderTotalType; +import com.salesmanager.core.model.order.orderstatus.OrderStatus; +import com.salesmanager.core.model.order.orderstatus.OrderStatusHistory; +import com.salesmanager.core.model.payments.CreditCardPayment; +import com.salesmanager.core.model.payments.CreditCardType; +import com.salesmanager.core.model.payments.Payment; +import com.salesmanager.core.model.payments.PaymentMethod; +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.payments.TransactionType; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.model.system.MerchantConfiguration; +import com.salesmanager.core.modules.integration.IntegrationException; +import com.salesmanager.core.modules.integration.payment.model.PaymentModule; +import com.salesmanager.core.modules.utils.Encryption; + + +@Service("paymentService") +public class PaymentServiceImpl implements PaymentService { + + + private static final Logger LOGGER = LoggerFactory.getLogger(PaymentServiceImpl.class); + + + @Inject + private MerchantConfigurationService merchantConfigurationService; + + @Inject + private ModuleConfigurationService moduleConfigurationService; + + @Inject + private TransactionService transactionService; + + @Inject + private OrderService orderService; + + @Inject + private CoreConfiguration coreConfiguration; + + @Inject + @Resource(name="paymentModules") + private Map paymentModules; + + @Inject + private Encryption encryption; + + @Override + public List getPaymentMethods(MerchantStore store) throws ServiceException { + + List modules = moduleConfigurationService.getIntegrationModules(Constants.PAYMENT_MODULES); + List returnModules = new ArrayList(); + + for(IntegrationModule module : modules) { + if(module.getRegionsSet().contains(store.getCountry().getIsoCode()) + || module.getRegionsSet().contains("*")) { + + returnModules.add(module); + } + } + + return returnModules; + } + + @Override + public List getAcceptedPaymentMethods(MerchantStore store) throws ServiceException { + + Map modules = this.getPaymentModulesConfigured(store); + + List returnModules = new ArrayList(); + + for(String module : modules.keySet()) { + IntegrationConfiguration config = modules.get(module); + if(config.isActive()) { + + IntegrationModule md = this.getPaymentMethodByCode(store, config.getModuleCode()); + if(md==null) { + continue; + } + PaymentMethod paymentMethod = new PaymentMethod(); + + paymentMethod.setDefaultSelected(config.isDefaultSelected()); + paymentMethod.setPaymentMethodCode(config.getModuleCode()); + paymentMethod.setModule(md); + paymentMethod.setInformations(config); + + PaymentType type = PaymentType.fromString(md.getType()); + + paymentMethod.setPaymentType(type); + returnModules.add(paymentMethod); + } + } + + return returnModules; + + + } + + @Override + public IntegrationModule getPaymentMethodByType(MerchantStore store, String type) throws ServiceException { + List modules = getPaymentMethods(store); + + for(IntegrationModule module : modules) { + if(module.getModule().equals(type)) { + + return module; + } + } + + return null; + } + + @Override + public IntegrationModule getPaymentMethodByCode(MerchantStore store, + String code) throws ServiceException { + List modules = getPaymentMethods(store); + + for(IntegrationModule module : modules) { + if(module.getCode().equals(code)) { + + return module; + } + } + + return null; + } + + @Override + public IntegrationConfiguration getPaymentConfiguration(String moduleCode, MerchantStore store) throws ServiceException { + + Validate.notNull(moduleCode,"Module code must not be null"); + Validate.notNull(store,"Store must not be null"); + + String mod = moduleCode.toLowerCase(); + + Map configuredModules = getPaymentModulesConfigured(store); + if(configuredModules!=null) { + for(String key : configuredModules.keySet()) { + if(key.equals(mod)) { + return configuredModules.get(key); + } + } + } + + return null; + + } + + + + @Override + public Map getPaymentModulesConfigured(MerchantStore store) throws ServiceException { + + try { + + Map modules = new HashMap(); + MerchantConfiguration merchantConfiguration = merchantConfigurationService.getMerchantConfiguration(Constants.PAYMENT_MODULES, store); + if(merchantConfiguration!=null) { + + if(!StringUtils.isBlank(merchantConfiguration.getValue())) { + + String decrypted = encryption.decrypt(merchantConfiguration.getValue()); + modules = ConfigurationModulesLoader.loadIntegrationConfigurations(decrypted); + + + } + } + return modules; + + } catch (Exception e) { + throw new ServiceException(e); + } + } + + @Override + public void savePaymentModuleConfiguration(IntegrationConfiguration configuration, MerchantStore store) throws ServiceException { + + //validate entries + try { + + String moduleCode = configuration.getModuleCode(); + PaymentModule module = paymentModules.get(moduleCode); + if(module==null) { + throw new ServiceException("Payment module " + moduleCode + " does not exist"); + } + module.validateModuleConfiguration(configuration, store); + + } catch (IntegrationException ie) { + throw ie; + } + + try { + Map modules = new HashMap(); + MerchantConfiguration merchantConfiguration = merchantConfigurationService.getMerchantConfiguration(Constants.PAYMENT_MODULES, store); + if(merchantConfiguration!=null) { + if(!StringUtils.isBlank(merchantConfiguration.getValue())) { + + String decrypted = encryption.decrypt(merchantConfiguration.getValue()); + + modules = ConfigurationModulesLoader.loadIntegrationConfigurations(decrypted); + } + } else { + merchantConfiguration = new MerchantConfiguration(); + merchantConfiguration.setMerchantStore(store); + merchantConfiguration.setKey(Constants.PAYMENT_MODULES); + } + modules.put(configuration.getModuleCode(), configuration); + + String configs = ConfigurationModulesLoader.toJSONString(modules); + + String encrypted = encryption.encrypt(configs); + merchantConfiguration.setValue(encrypted); + + merchantConfigurationService.saveOrUpdate(merchantConfiguration); + + } catch (Exception e) { + throw new ServiceException(e); + } + } + + @Override + public void removePaymentModuleConfiguration(String moduleCode, MerchantStore store) throws ServiceException { + + + + try { + Map modules = new HashMap(); + MerchantConfiguration merchantConfiguration = merchantConfigurationService.getMerchantConfiguration(Constants.PAYMENT_MODULES, store); + if(merchantConfiguration!=null) { + + if(!StringUtils.isBlank(merchantConfiguration.getValue())) { + + String decrypted = encryption.decrypt(merchantConfiguration.getValue()); + modules = ConfigurationModulesLoader.loadIntegrationConfigurations(decrypted); + } + + modules.remove(moduleCode); + String configs = ConfigurationModulesLoader.toJSONString(modules); + + String encrypted = encryption.encrypt(configs); + merchantConfiguration.setValue(encrypted); + + merchantConfigurationService.saveOrUpdate(merchantConfiguration); + + + } + + MerchantConfiguration configuration = merchantConfigurationService.getMerchantConfiguration(moduleCode, store); + + if(configuration!=null) {//custom module + + merchantConfigurationService.delete(configuration); + } + + + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + + + + + @Override + public Transaction processPayment(Customer customer, + MerchantStore store, Payment payment, List items, Order order) + throws ServiceException { + + + Validate.notNull(customer); + Validate.notNull(store); + Validate.notNull(payment); + Validate.notNull(order); + Validate.notNull(order.getTotal()); + + payment.setCurrency(store.getCurrency()); + + BigDecimal amount = order.getTotal(); + + //must have a shipping module configured + Map modules = this.getPaymentModulesConfigured(store); + if(modules==null){ + throw new ServiceException("No payment module configured"); + } + + IntegrationConfiguration configuration = modules.get(payment.getModuleName()); + + if(configuration==null) { + throw new ServiceException("Payment module " + payment.getModuleName() + " is not configured"); + } + + if(!configuration.isActive()) { + throw new ServiceException("Payment module " + payment.getModuleName() + " is not active"); + } + + String sTransactionType = configuration.getIntegrationKeys().get("transaction"); + if(sTransactionType==null) { + sTransactionType = TransactionType.AUTHORIZECAPTURE.name(); + } + + try { + TransactionType.valueOf(sTransactionType); + } catch(IllegalArgumentException ie) { + LOGGER.warn("Transaction type " + sTransactionType + " does noe exist, using default AUTHORIZECAPTURE"); + sTransactionType = "AUTHORIZECAPTURE"; + } + + + + if(sTransactionType.equals(TransactionType.AUTHORIZE.name())) { + payment.setTransactionType(TransactionType.AUTHORIZE); + } else { + payment.setTransactionType(TransactionType.AUTHORIZECAPTURE); + } + + + PaymentModule module = this.paymentModules.get(payment.getModuleName()); + + if(module==null) { + throw new ServiceException("Payment module " + payment.getModuleName() + " does not exist"); + } + + if(payment instanceof CreditCardPayment && "true".equals(coreConfiguration.getProperty("VALIDATE_CREDIT_CARD"))) { + CreditCardPayment creditCardPayment = (CreditCardPayment)payment; + validateCreditCard(creditCardPayment.getCreditCardNumber(),creditCardPayment.getCreditCard(),creditCardPayment.getExpirationMonth(),creditCardPayment.getExpirationYear()); + } + + IntegrationModule integrationModule = getPaymentMethodByCode(store,payment.getModuleName()); + TransactionType transactionType = TransactionType.valueOf(sTransactionType); + if(transactionType==null) { + transactionType = payment.getTransactionType(); + if(transactionType.equals(TransactionType.CAPTURE.name())) { + throw new ServiceException("This method does not allow to process capture transaction. Use processCapturePayment"); + } + } + + Transaction transaction = null; + if(transactionType == TransactionType.AUTHORIZE) { + transaction = module.authorize(store, customer, items, amount, payment, configuration, integrationModule); + } else if(transactionType == TransactionType.AUTHORIZECAPTURE) { + transaction = module.authorizeAndCapture(store, customer, items, amount, payment, configuration, integrationModule); + } else if(transactionType == TransactionType.INIT) { + transaction = module.initTransaction(store, customer, amount, payment, configuration, integrationModule); + } + + + if(transactionType != TransactionType.INIT) { + transactionService.create(transaction); + } + + if(transactionType == TransactionType.AUTHORIZECAPTURE) { + order.setStatus(OrderStatus.ORDERED); + if(!payment.getPaymentType().name().equals(PaymentType.MONEYORDER.name())) { + order.setStatus(OrderStatus.PROCESSED); + } + } + + return transaction; + + + + } + + @Override + public PaymentModule getPaymentModule(String paymentModuleCode) throws ServiceException { + return paymentModules.get(paymentModuleCode); + } + + @Override + public Transaction processCapturePayment(Order order, Customer customer, + MerchantStore store) + throws ServiceException { + + + Validate.notNull(customer); + Validate.notNull(store); + Validate.notNull(order); + + + + //must have a shipping module configured + Map modules = this.getPaymentModulesConfigured(store); + if(modules==null){ + throw new ServiceException("No payment module configured"); + } + + IntegrationConfiguration configuration = modules.get(order.getPaymentModuleCode()); + + if(configuration==null) { + throw new ServiceException("Payment module " + order.getPaymentModuleCode() + " is not configured"); + } + + if(!configuration.isActive()) { + throw new ServiceException("Payment module " + order.getPaymentModuleCode() + " is not active"); + } + + + PaymentModule module = this.paymentModules.get(order.getPaymentModuleCode()); + + if(module==null) { + throw new ServiceException("Payment module " + order.getPaymentModuleCode() + " does not exist"); + } + + + IntegrationModule integrationModule = getPaymentMethodByCode(store,order.getPaymentModuleCode()); + + //TransactionType transactionType = payment.getTransactionType(); + + //get the previous transaction + Transaction trx = transactionService.getCapturableTransaction(order); + if(trx==null) { + throw new ServiceException("No capturable transaction for order id " + order.getId()); + } + Transaction transaction = module.capture(store, customer, order, trx, configuration, integrationModule); + transaction.setOrder(order); + + + + transactionService.create(transaction); + + + OrderStatusHistory orderHistory = new OrderStatusHistory(); + orderHistory.setOrder(order); + orderHistory.setStatus(OrderStatus.PROCESSED); + orderHistory.setDateAdded(new Date()); + + orderService.addOrderStatusHistory(order, orderHistory); + + order.setStatus(OrderStatus.PROCESSED); + orderService.saveOrUpdate(order); + + return transaction; + + + + } + + @Override + public Transaction processRefund(Order order, Customer customer, + MerchantStore store, BigDecimal amount) + throws ServiceException { + + + Validate.notNull(customer); + Validate.notNull(store); + Validate.notNull(amount); + Validate.notNull(order); + Validate.notNull(order.getOrderTotal()); + + + BigDecimal orderTotal = order.getTotal(); + + if(amount.doubleValue()>orderTotal.doubleValue()) { + throw new ServiceException("Invalid amount, the refunded amount is greater than the total allowed"); + } + + + String module = order.getPaymentModuleCode(); + Map modules = this.getPaymentModulesConfigured(store); + if(modules==null){ + throw new ServiceException("No payment module configured"); + } + + IntegrationConfiguration configuration = modules.get(module); + + if(configuration==null) { + throw new ServiceException("Payment module " + module + " is not configured"); + } + + PaymentModule paymentModule = this.paymentModules.get(module); + + if(paymentModule==null) { + throw new ServiceException("Payment module " + paymentModule + " does not exist"); + } + + boolean partial = false; + if(amount.doubleValue()!=order.getTotal().doubleValue()) { + partial = true; + } + + IntegrationModule integrationModule = getPaymentMethodByCode(store,module); + + //get the associated transaction + Transaction refundable = transactionService.getRefundableTransaction(order); + + if(refundable==null) { + throw new ServiceException("No refundable transaction for this order"); + } + + Transaction transaction = paymentModule.refund(partial, store, refundable, order, amount, configuration, integrationModule); + transaction.setOrder(order); + transactionService.create(transaction); + + OrderTotal refund = new OrderTotal(); + refund.setModule(Constants.OT_REFUND_MODULE_CODE); + refund.setText(Constants.OT_REFUND_MODULE_CODE); + refund.setTitle(Constants.OT_REFUND_MODULE_CODE); + refund.setOrderTotalCode(Constants.OT_REFUND_MODULE_CODE); + refund.setOrderTotalType(OrderTotalType.REFUND); + refund.setValue(amount); + refund.setSortOrder(100); + refund.setOrder(order); + + order.getOrderTotal().add(refund); + + //update order total + orderTotal = orderTotal.subtract(amount); + + //update ordertotal refund + Set totals = order.getOrderTotal(); + for(OrderTotal total : totals) { + if(total.getModule().equals(Constants.OT_TOTAL_MODULE_CODE)) { + total.setValue(orderTotal); + } + } + + + + order.setTotal(orderTotal); + order.setStatus(OrderStatus.REFUNDED); + + + + OrderStatusHistory orderHistory = new OrderStatusHistory(); + orderHistory.setOrder(order); + orderHistory.setStatus(OrderStatus.REFUNDED); + orderHistory.setDateAdded(new Date()); + order.getOrderHistory().add(orderHistory); + + orderService.saveOrUpdate(order); + + return transaction; + } + + @Override + public void validateCreditCard(String number, CreditCardType creditCard, String month, String date) + throws ServiceException { + + try { + Integer.parseInt(month); + Integer.parseInt(date); + } catch (NumberFormatException nfe) { + throw new ServiceException(ServiceException.EXCEPTION_VALIDATION,"Invalid date format","messages.error.creditcard.dateformat"); + } + + if (StringUtils.isBlank(number)) { + throw new ServiceException(ServiceException.EXCEPTION_VALIDATION,"Invalid card number","messages.error.creditcard.number"); + } + + Matcher m = Pattern.compile("[^\\d\\s.-]").matcher(number); + + if (m.find()) { + throw new ServiceException(ServiceException.EXCEPTION_VALIDATION,"Invalid card number","messages.error.creditcard.number"); + } + + Matcher matcher = Pattern.compile("[\\s.-]").matcher(number); + + number = matcher.replaceAll(""); + validateCreditCardDate(Integer.parseInt(month), Integer.parseInt(date)); + validateCreditCardNumber(number, creditCard); + } + + private void validateCreditCardDate(int m, int y) throws ServiceException { + java.util.Calendar cal = new java.util.GregorianCalendar(); + int monthNow = cal.get(java.util.Calendar.MONTH) + 1; + int yearNow = cal.get(java.util.Calendar.YEAR); + if (yearNow > y) { + throw new ServiceException(ServiceException.EXCEPTION_VALIDATION,"Invalid date format","messages.error.creditcard.dateformat"); + } + // OK, change implementation + if (yearNow == y && monthNow > m) { + throw new ServiceException(ServiceException.EXCEPTION_VALIDATION,"Invalid date format","messages.error.creditcard.dateformat"); + } + + } + + @Deprecated + /** + * Use commons validator CreditCardValidator + * @param number + * @param creditCard + * @throws ServiceException + */ + private void validateCreditCardNumber(String number, CreditCardType creditCard) + throws ServiceException { + + //TODO implement + if(CreditCardType.MASTERCARD.equals(creditCard.name())) { + if (number.length() != 16 + || Integer.parseInt(number.substring(0, 2)) < 51 + || Integer.parseInt(number.substring(0, 2)) > 55) { + throw new ServiceException(ServiceException.EXCEPTION_VALIDATION,"Invalid card number","messages.error.creditcard.number"); + } + } + + if(CreditCardType.VISA.equals(creditCard.name())) { + if ((number.length() != 13 && number.length() != 16) + || Integer.parseInt(number.substring(0, 1)) != 4) { + throw new ServiceException(ServiceException.EXCEPTION_VALIDATION,"Invalid card number","messages.error.creditcard.number"); + } + } + + if(CreditCardType.AMEX.equals(creditCard.name())) { + if (number.length() != 15 + || (Integer.parseInt(number.substring(0, 2)) != 34 && Integer + .parseInt(number.substring(0, 2)) != 37)) { + throw new ServiceException(ServiceException.EXCEPTION_VALIDATION,"Invalid card number","messages.error.creditcard.number"); + } + } + + if(CreditCardType.DINERS.equals(creditCard.name())) { + if (number.length() != 14 + || ((Integer.parseInt(number.substring(0, 2)) != 36 && Integer + .parseInt(number.substring(0, 2)) != 38) + && Integer.parseInt(number.substring(0, 3)) < 300 || Integer + .parseInt(number.substring(0, 3)) > 305)) { + throw new ServiceException(ServiceException.EXCEPTION_VALIDATION,"Invalid card number","messages.error.creditcard.number"); + } + } + + if(CreditCardType.DISCOVERY.equals(creditCard.name())) { + if (number.length() != 16 + || Integer.parseInt(number.substring(0, 5)) != 6011) { + throw new ServiceException(ServiceException.EXCEPTION_VALIDATION,"Invalid card number","messages.error.creditcard.number"); + } + } + + luhnValidate(number); + } + + // The Luhn algorithm is basically a CRC type + // system for checking the validity of an entry. + // All major credit cards use numbers that will + // pass the Luhn check. Also, all of them are based + // on MOD 10. + @Deprecated + private void luhnValidate(String numberString) + throws ServiceException { + char[] charArray = numberString.toCharArray(); + int[] number = new int[charArray.length]; + int total = 0; + + for (int i = 0; i < charArray.length; i++) { + number[i] = Character.getNumericValue(charArray[i]); + } + + for (int i = number.length - 2; i > -1; i -= 2) { + number[i] *= 2; + + if (number[i] > 9) + number[i] -= 9; + } + + for (int j : number) { + total += j; + } + + if (total % 10 != 0) { + throw new ServiceException(ServiceException.EXCEPTION_VALIDATION,"Invalid card number","messages.error.creditcard.number"); + } + + } + + @Override + public Transaction initTransaction(Order order, Customer customer, Payment payment, MerchantStore store) throws ServiceException { + + Validate.notNull(store); + Validate.notNull(payment); + Validate.notNull(order); + Validate.notNull(order.getTotal()); + + payment.setCurrency(store.getCurrency()); + + BigDecimal amount = order.getTotal(); + + //must have a shipping module configured + Map modules = this.getPaymentModulesConfigured(store); + if(modules==null){ + throw new ServiceException("No payment module configured"); + } + + IntegrationConfiguration configuration = modules.get(payment.getModuleName()); + + if(configuration==null) { + throw new ServiceException("Payment module " + payment.getModuleName() + " is not configured"); + } + + if(!configuration.isActive()) { + throw new ServiceException("Payment module " + payment.getModuleName() + " is not active"); + } + + PaymentModule module = this.paymentModules.get(order.getPaymentModuleCode()); + + if(module==null) { + throw new ServiceException("Payment module " + order.getPaymentModuleCode() + " does not exist"); + } + + IntegrationModule integrationModule = getPaymentMethodByCode(store,payment.getModuleName()); + + return module.initTransaction(store, customer, amount, payment, configuration, integrationModule); + } + + @Override + public Transaction initTransaction(Customer customer, Payment payment, MerchantStore store) throws ServiceException { + + Validate.notNull(store); + Validate.notNull(payment); + Validate.notNull(payment.getAmount()); + + payment.setCurrency(store.getCurrency()); + + BigDecimal amount = payment.getAmount(); + + //must have a shipping module configured + Map modules = this.getPaymentModulesConfigured(store); + if(modules==null){ + throw new ServiceException("No payment module configured"); + } + + IntegrationConfiguration configuration = modules.get(payment.getModuleName()); + + if(configuration==null) { + throw new ServiceException("Payment module " + payment.getModuleName() + " is not configured"); + } + + if(!configuration.isActive()) { + throw new ServiceException("Payment module " + payment.getModuleName() + " is not active"); + } + + PaymentModule module = this.paymentModules.get(payment.getModuleName()); + + if(module==null) { + throw new ServiceException("Payment module " + payment.getModuleName() + " does not exist"); + } + + IntegrationModule integrationModule = getPaymentMethodByCode(store,payment.getModuleName()); + + Transaction transaction = module.initTransaction(store, customer, amount, payment, configuration, integrationModule); + + transactionService.save(transaction); + + return transaction; + } + + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/payments/TransactionService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/payments/TransactionService.java new file mode 100755 index 0000000000..cd901dc3dd --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/payments/TransactionService.java @@ -0,0 +1,35 @@ +package com.salesmanager.core.business.services.payments; + +import java.util.Date; +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.payments.Transaction; + + + + +public interface TransactionService extends SalesManagerEntityService { + + /** + * Obtain a previous transaction that has type authorize for a give order + * @param order + * @return + * @throws ServiceException + */ + Transaction getCapturableTransaction(Order order) throws ServiceException; + + Transaction getRefundableTransaction(Order order) throws ServiceException; + + List listTransactions(Order order) throws ServiceException; + + List listTransactions(Date startDate, Date endDate) throws ServiceException; + + Transaction lastTransaction(Order order, MerchantStore store) throws ServiceException; + + + +} \ No newline at end of file diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/payments/TransactionServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/payments/TransactionServiceImpl.java new file mode 100755 index 0000000000..7cc989673f --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/payments/TransactionServiceImpl.java @@ -0,0 +1,208 @@ +package com.salesmanager.core.business.services.payments; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.payments.TransactionRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.payments.TransactionType; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import javax.inject.Inject; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; +import java.util.stream.Collectors; + + + +@Service("transactionService") +public class TransactionServiceImpl extends SalesManagerEntityServiceImpl implements TransactionService { + + + private TransactionRepository transactionRepository; + + @Inject + public TransactionServiceImpl(TransactionRepository transactionRepository) { + super(transactionRepository); + this.transactionRepository = transactionRepository; + } + + @Override + public void create(Transaction transaction) throws ServiceException { + + //parse JSON string + String transactionDetails = transaction.toJSONString(); + if(!StringUtils.isBlank(transactionDetails)) { + transaction.setDetails(transactionDetails); + } + + super.create(transaction); + + + } + + @Override + public List listTransactions(Order order) throws ServiceException { + + List transactions = transactionRepository.findByOrder(order.getId()); + ObjectMapper mapper = new ObjectMapper(); + for(Transaction transaction : transactions) { + if(!StringUtils.isBlank(transaction.getDetails())) { + try { + @SuppressWarnings("unchecked") + Map objects = mapper.readValue(transaction.getDetails(), Map.class); + transaction.setTransactionDetails(objects); + } catch (Exception e) { + throw new ServiceException(e); + } + } + } + + return transactions; + } + + /** + * Authorize + * AuthorizeAndCapture + * Capture + * Refund + * + * Check transactions + * next transaction flow is + * Build map of transactions map + * filter get last from date + * get last transaction type + * verify which step transaction it if + * check if target transaction is in transaction map we are in trouble... + * + */ + public Transaction lastTransaction(Order order, MerchantStore store) throws ServiceException { + + List transactions = transactionRepository.findByOrder(order.getId()); + //ObjectMapper mapper = new ObjectMapper(); + + //TODO order by date + TreeMap map = transactions.stream() + .collect( + + Collectors.toMap( + Transaction::getTransactionTypeName, transaction -> transaction,(o1, o2) -> o1, TreeMap::new) + + + ); + + + + //get last transaction + Entry last = map.lastEntry(); + + String currentStep = last.getKey(); + + System.out.println("Current step " + currentStep); + + //find next step + + return last.getValue(); + + + + } + + @Override + public Transaction getCapturableTransaction(Order order) + throws ServiceException { + List transactions = transactionRepository.findByOrder(order.getId()); + ObjectMapper mapper = new ObjectMapper(); + Transaction capturable = null; + for(Transaction transaction : transactions) { + if(transaction.getTransactionType().name().equals(TransactionType.AUTHORIZE.name())) { + if(!StringUtils.isBlank(transaction.getDetails())) { + try { + @SuppressWarnings("unchecked") + Map objects = mapper.readValue(transaction.getDetails(), Map.class); + transaction.setTransactionDetails(objects); + capturable = transaction; + } catch (Exception e) { + throw new ServiceException(e); + } + } + } + if(transaction.getTransactionType().name().equals(TransactionType.CAPTURE.name())) { + break; + } + if(transaction.getTransactionType().name().equals(TransactionType.REFUND.name())) { + break; + } + } + + return capturable; + } + + @Override + public Transaction getRefundableTransaction(Order order) + throws ServiceException { + List transactions = transactionRepository.findByOrder(order.getId()); + Map finalTransactions = new HashMap(); + Transaction finalTransaction = null; + for(Transaction transaction : transactions) { + if(transaction.getTransactionType().name().equals(TransactionType.AUTHORIZECAPTURE.name())) { + finalTransactions.put(TransactionType.AUTHORIZECAPTURE.name(),transaction); + continue; + } + if(transaction.getTransactionType().name().equals(TransactionType.CAPTURE.name())) { + finalTransactions.put(TransactionType.CAPTURE.name(),transaction); + continue; + } + if(transaction.getTransactionType().name().equals(TransactionType.REFUND.name())) { + //check transaction id + Transaction previousRefund = finalTransactions.get(TransactionType.REFUND.name()); + if(previousRefund!=null) { + Date previousDate = previousRefund.getTransactionDate(); + Date currentDate = transaction.getTransactionDate(); + if(previousDate.before(currentDate)) { + finalTransactions.put(TransactionType.REFUND.name(),transaction); + continue; + } + } else { + finalTransactions.put(TransactionType.REFUND.name(),transaction); + continue; + } + } + } + + if(finalTransactions.containsKey(TransactionType.AUTHORIZECAPTURE.name())) { + finalTransaction = finalTransactions.get(TransactionType.AUTHORIZECAPTURE.name()); + } + + if(finalTransactions.containsKey(TransactionType.CAPTURE.name())) { + finalTransaction = finalTransactions.get(TransactionType.CAPTURE.name()); + } + + if(finalTransaction!=null && !StringUtils.isBlank(finalTransaction.getDetails())) { + try { + ObjectMapper mapper = new ObjectMapper(); + @SuppressWarnings("unchecked") + Map objects = mapper.readValue(finalTransaction.getDetails(), Map.class); + finalTransaction.setTransactionDetails(objects); + } catch (Exception e) { + throw new ServiceException(e); + } + } + + return finalTransaction; + } + + @Override + public List listTransactions(Date startDate, Date endDate) throws ServiceException { + + return transactionRepository.findByDates(startDate, endDate); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/reference/country/CountryService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/country/CountryService.java new file mode 100755 index 0000000000..6009a629db --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/country/CountryService.java @@ -0,0 +1,34 @@ +package com.salesmanager.core.business.services.reference.country; + +import java.util.List; +import java.util.Map; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.country.CountryDescription; +import com.salesmanager.core.model.reference.language.Language; + +public interface CountryService extends SalesManagerEntityService { + + Country getByCode(String code) throws ServiceException; + + void addCountryDescription(Country country, CountryDescription description) throws ServiceException; + + List getCountries(Language language) throws ServiceException; + + Map getCountriesMap(Language language) + throws ServiceException; + + List getCountries(List isoCodes, Language language) + throws ServiceException; + + + /** + * List country - zone objects by language + * @param language + * @return + * @throws ServiceException + */ + List listCountryZones(Language language) throws ServiceException; +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/reference/country/CountryServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/country/CountryServiceImpl.java new file mode 100755 index 0000000000..993d96075f --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/country/CountryServiceImpl.java @@ -0,0 +1,129 @@ +package com.salesmanager.core.business.services.reference.country; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.reference.country.CountryRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.business.utils.CacheUtils; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.country.CountryDescription; +import com.salesmanager.core.model.reference.language.Language; + +@Service("countryService") +public class CountryServiceImpl extends SalesManagerEntityServiceImpl + implements CountryService { + + private static final Logger LOGGER = LoggerFactory.getLogger(CountryServiceImpl.class); + + private CountryRepository countryRepository; + + @Inject + private CacheUtils cache; + + + @Inject + public CountryServiceImpl(CountryRepository countryRepository) { + super(countryRepository); + this.countryRepository = countryRepository; + } + + @Cacheable("countrByCode") + public Country getByCode(String code) throws ServiceException { + return countryRepository.findByIsoCode(code); + } + + @Override + public void addCountryDescription(Country country, CountryDescription description) throws ServiceException { + country.getDescriptions().add(description); + description.setCountry(country); + update(country); + } + + @Override + @Cacheable("countriesMap") + public Map getCountriesMap(Language language) throws ServiceException { + + List countries = getCountries(language); + + Map returnMap = new LinkedHashMap(); + + for(Country country : countries) { + returnMap.put(country.getIsoCode(), country); + } + + return returnMap; + } + + + @Override + public List getCountries(final List isoCodes, final Language language) throws ServiceException { + List countryList = getCountries(language); + List requestedCountryList = new ArrayList(); + if(!CollectionUtils.isEmpty(countryList)) { + for(Country c : countryList) { + if(isoCodes.contains(c.getIsoCode())) { + requestedCountryList.add(c); + } + } + } + return requestedCountryList; + } + + + @SuppressWarnings("unchecked") + @Override + public List getCountries(Language language) throws ServiceException { + + List countries = null; + try { + + countries = (List) cache.getFromCache("COUNTRIES_" + language.getCode()); + if(countries==null) { + + countries = countryRepository.listByLanguage(language.getId()); + + //set names + for(Country country : countries) { + + CountryDescription description = country.getDescriptions().iterator().next(); + country.setName(description.getName()); + + } + + cache.putInCache(countries, "COUNTRIES_" + language.getCode()); + } + + } catch (Exception e) { + LOGGER.error("getCountries()", e); + } + + return countries; + + + } + + @Override + public List listCountryZones(Language language) throws ServiceException { + try { + return countryRepository.listCountryZonesByLanguage(language.getId()); + } catch(Exception e) { + LOGGER.error("listCountryZones", e); + throw new ServiceException(e); + } + + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/reference/currency/CurrencyService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/currency/CurrencyService.java new file mode 100755 index 0000000000..3aa6548fef --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/currency/CurrencyService.java @@ -0,0 +1,10 @@ +package com.salesmanager.core.business.services.reference.currency; + +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.reference.currency.Currency; + +public interface CurrencyService extends SalesManagerEntityService { + + Currency getByCode(String code); + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/reference/currency/CurrencyServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/currency/CurrencyServiceImpl.java new file mode 100755 index 0000000000..76858f704b --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/currency/CurrencyServiceImpl.java @@ -0,0 +1,28 @@ +package com.salesmanager.core.business.services.reference.currency; + +import javax.inject.Inject; + +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.repositories.reference.currency.CurrencyRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.reference.currency.Currency; + +@Service("currencyService") +public class CurrencyServiceImpl extends SalesManagerEntityServiceImpl + implements CurrencyService { + + private CurrencyRepository currencyRepository; + + @Inject + public CurrencyServiceImpl(CurrencyRepository currencyRepository) { + super(currencyRepository); + this.currencyRepository = currencyRepository; + } + + @Override + public Currency getByCode(String code) { + return currencyRepository.getByCode(code); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/reference/init/InitializationDatabase.java b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/init/InitializationDatabase.java new file mode 100755 index 0000000000..3163e726e6 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/init/InitializationDatabase.java @@ -0,0 +1,11 @@ +package com.salesmanager.core.business.services.reference.init; + +import com.salesmanager.core.business.exception.ServiceException; + +public interface InitializationDatabase { + + boolean isEmpty(); + + void populate(String name) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/reference/init/InitializationDatabaseImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/init/InitializationDatabaseImpl.java new file mode 100755 index 0000000000..502cc52943 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/init/InitializationDatabaseImpl.java @@ -0,0 +1,476 @@ +package com.salesmanager.core.business.services.reference.init; + +import java.sql.Date; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import javax.inject.Inject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.product.manufacturer.ManufacturerService; +import com.salesmanager.core.business.services.catalog.product.type.ProductTypeService; +import com.salesmanager.core.business.services.merchant.MerchantStoreService; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.currency.CurrencyService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.services.reference.loader.IntegrationModulesLoader; +import com.salesmanager.core.business.services.reference.loader.ZonesLoader; +import com.salesmanager.core.business.services.reference.zone.ZoneService; +import com.salesmanager.core.business.services.system.ModuleConfigurationService; +import com.salesmanager.core.business.services.system.optin.OptinService; +import com.salesmanager.core.business.services.tax.TaxClassService; +import com.salesmanager.core.business.services.user.GroupService; +import com.salesmanager.core.business.services.user.PermissionService; +import com.salesmanager.core.business.utils.SecurityGroupsBuilder; +import com.salesmanager.core.constants.SchemaConstant; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.catalog.product.manufacturer.ManufacturerDescription; +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.country.CountryDescription; +import com.salesmanager.core.model.reference.currency.Currency; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.core.model.reference.zone.ZoneDescription; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.model.system.optin.Optin; +import com.salesmanager.core.model.system.optin.OptinType; +import com.salesmanager.core.model.tax.taxclass.TaxClass; +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.model.user.GroupType; +import com.salesmanager.core.model.user.Permission; + +@Service("initializationDatabase") +public class InitializationDatabaseImpl implements InitializationDatabase { + + private static final Logger LOGGER = LoggerFactory.getLogger(InitializationDatabaseImpl.class); + + + @Inject + private ZoneService zoneService; + + @Inject + private LanguageService languageService; + + @Inject + private CountryService countryService; + + @Inject + private CurrencyService currencyService; + + @Inject + protected MerchantStoreService merchantService; + + @Inject + protected ProductTypeService productTypeService; + + @Inject + private TaxClassService taxClassService; + + @Inject + private ZonesLoader zonesLoader; + + @Inject + private IntegrationModulesLoader modulesLoader; + + @Inject + private ManufacturerService manufacturerService; + + @Inject + private ModuleConfigurationService moduleConfigurationService; + + @Inject + private OptinService optinService; + + @Inject + protected GroupService groupService; + + @Inject + protected PermissionService permissionService; + + private String name; + + public boolean isEmpty() { + return languageService.count() == 0; + } + + @Transactional + public void populate(String contextName) throws ServiceException { + this.name = contextName; + + createSecurityGroups(); + createLanguages(); + createCountries(); + createZones(); + createCurrencies(); + createSubReferences(); + createModules(); + createMerchant(); + + + } + + private void createSecurityGroups() throws ServiceException { + + //create permissions + //Map name object + Map permissionKeys = new HashMap(); + Permission AUTH = new Permission("AUTH"); + permissionService.create(AUTH); + permissionKeys.put(AUTH.getPermissionName(), AUTH); + + Permission SUPERADMIN = new Permission("SUPERADMIN"); + permissionService.create(SUPERADMIN); + permissionKeys.put(SUPERADMIN.getPermissionName(), SUPERADMIN); + + Permission ADMIN = new Permission("ADMIN"); + permissionService.create(ADMIN); + permissionKeys.put(ADMIN.getPermissionName(), ADMIN); + + Permission PRODUCTS = new Permission("PRODUCTS"); + permissionService.create(PRODUCTS); + permissionKeys.put(PRODUCTS.getPermissionName(), PRODUCTS); + + Permission ORDER = new Permission("ORDER"); + permissionService.create(ORDER); + permissionKeys.put(ORDER.getPermissionName(), ORDER); + + Permission CONTENT = new Permission("CONTENT"); + permissionService.create(CONTENT); + permissionKeys.put(CONTENT.getPermissionName(), CONTENT); + + Permission STORE = new Permission("STORE"); + permissionService.create(STORE); + permissionKeys.put(STORE.getPermissionName(), STORE); + + Permission TAX = new Permission("TAX"); + permissionService.create(TAX); + permissionKeys.put(TAX.getPermissionName(), TAX); + + Permission PAYMENT = new Permission("PAYMENT"); + permissionService.create(PAYMENT); + permissionKeys.put(PAYMENT.getPermissionName(), PAYMENT); + + Permission CUSTOMER = new Permission("CUSTOMER"); + permissionService.create(CUSTOMER); + permissionKeys.put(CUSTOMER.getPermissionName(), CUSTOMER); + + Permission SHIPPING = new Permission("SHIPPING"); + permissionService.create(SHIPPING); + permissionKeys.put(SHIPPING.getPermissionName(), SHIPPING); + + Permission AUTH_CUSTOMER = new Permission("AUTH_CUSTOMER"); + permissionService.create(AUTH_CUSTOMER); + permissionKeys.put(AUTH_CUSTOMER.getPermissionName(), AUTH_CUSTOMER); + + SecurityGroupsBuilder groupBuilder = new SecurityGroupsBuilder(); + groupBuilder + .addGroup("SUPERADMIN", GroupType.ADMIN) + .addPermission(permissionKeys.get("AUTH")) + .addPermission(permissionKeys.get("SUPERADMIN")) + .addPermission(permissionKeys.get("ADMIN")) + .addPermission(permissionKeys.get("PRODUCTS")) + .addPermission(permissionKeys.get("ORDER")) + .addPermission(permissionKeys.get("CONTENT")) + .addPermission(permissionKeys.get("STORE")) + .addPermission(permissionKeys.get("TAX")) + .addPermission(permissionKeys.get("PAYMENT")) + .addPermission(permissionKeys.get("CUSTOMER")) + .addPermission(permissionKeys.get("SHIPPING")) + + .addGroup("ADMIN", GroupType.ADMIN) + .addPermission(permissionKeys.get("AUTH")) + .addPermission(permissionKeys.get("ADMIN")) + .addPermission(permissionKeys.get("PRODUCTS")) + .addPermission(permissionKeys.get("ORDER")) + .addPermission(permissionKeys.get("CONTENT")) + .addPermission(permissionKeys.get("STORE")) + .addPermission(permissionKeys.get("TAX")) + .addPermission(permissionKeys.get("PAYMENT")) + .addPermission(permissionKeys.get("CUSTOMER")) + .addPermission(permissionKeys.get("SHIPPING")) + + .addGroup("ADMIN_RETAILER", GroupType.ADMIN) + .addPermission(permissionKeys.get("AUTH")) + .addPermission(permissionKeys.get("ADMIN")) + .addPermission(permissionKeys.get("PRODUCTS")) + .addPermission(permissionKeys.get("ORDER")) + .addPermission(permissionKeys.get("CONTENT")) + .addPermission(permissionKeys.get("STORE")) + .addPermission(permissionKeys.get("TAX")) + .addPermission(permissionKeys.get("PAYMENT")) + .addPermission(permissionKeys.get("CUSTOMER")) + .addPermission(permissionKeys.get("SHIPPING")) + + .addGroup("ADMIN_STORE", GroupType.ADMIN) + .addPermission(permissionKeys.get("AUTH")) + .addPermission(permissionKeys.get("CONTENT")) + .addPermission(permissionKeys.get("STORE")) + .addPermission(permissionKeys.get("TAX")) + .addPermission(permissionKeys.get("PAYMENT")) + .addPermission(permissionKeys.get("CUSTOMER")) + .addPermission(permissionKeys.get("SHIPPING")) + + .addGroup("ADMIN_CATALOGUE", GroupType.ADMIN) + .addPermission(permissionKeys.get("AUTH")) + .addPermission(permissionKeys.get("PRODUCTS")) + + .addGroup("ADMIN_ORDER", GroupType.ADMIN) + .addPermission(permissionKeys.get("AUTH")) + .addPermission(permissionKeys.get("ORDER")) + + .addGroup("ADMIN_CONTENT", GroupType.ADMIN) + .addPermission(permissionKeys.get("AUTH")) + .addPermission(permissionKeys.get("CONTENT")) + + .addGroup("CUSTOMER", GroupType.CUSTOMER) + .addPermission(permissionKeys.get("AUTH")) + .addPermission(permissionKeys.get("AUTH_CUSTOMER")); + + for(Group g : groupBuilder.build()) { + groupService.create(g); + } + + + } + + + + private void createCurrencies() throws ServiceException { + LOGGER.info(String.format("%s : Populating Currencies ", name)); + + for (String code : SchemaConstant.CURRENCY_MAP.keySet()) { + + try { + java.util.Currency c = java.util.Currency.getInstance(code); + + if(c==null) { + LOGGER.info(String.format("%s : Populating Currencies : no currency for code : %s", name, code)); + } + + //check if it exist + + Currency currency = new Currency(); + currency.setName(c.getCurrencyCode()); + currency.setCurrency(c); + currencyService.create(currency); + + //System.out.println(l.getCountry() + " " + c.getSymbol() + " " + c.getSymbol(l)); + } catch (IllegalArgumentException e) { + LOGGER.info(String.format("%s : Populating Currencies : no currency for code : %s", name, code)); + } + } + } + + private void createCountries() throws ServiceException { + LOGGER.info(String.format("%s : Populating Countries ", name)); + List languages = languageService.list(); + for(String code : SchemaConstant.COUNTRY_ISO_CODE) { + Locale locale = SchemaConstant.LOCALES.get(code); + if (locale != null) { + Country country = new Country(code); + countryService.create(country); + + for (Language language : languages) { + String name = locale.getDisplayCountry(new Locale(language.getCode())); + //byte[] ptext = value.getBytes(Constants.ISO_8859_1); + //String name = new String(ptext, Constants.UTF_8); + CountryDescription description = new CountryDescription(language, name); + countryService.addCountryDescription(country, description); + } + } + } + } + + private void createZones() throws ServiceException { + LOGGER.info(String.format("%s : Populating Zones ", name)); + try { + + Map zonesMap = new HashMap(); + zonesMap = zonesLoader.loadZones("reference/zoneconfig.json"); + + this.addZonesToDb(zonesMap); +/* + for (Map.Entry entry : zonesMap.entrySet()) { + String key = entry.getKey(); + Zone value = entry.getValue(); + if(value.getDescriptions()==null) { + LOGGER.warn("This zone " + key + " has no descriptions"); + continue; + } + + List zoneDescriptions = value.getDescriptions(); + value.setDescriptons(null); + + zoneService.create(value); + + for(ZoneDescription description : zoneDescriptions) { + description.setZone(value); + zoneService.addDescription(value, description); + } + }*/ + + //lookup additional zones + //iterate configured languages + LOGGER.info("Populating additional zones"); + + //load reference/zones/* (zone config for additional country) + //example in.json and in-fr.son + //will load es zones and use a specific file for french es zones + List> loadIndividualZones = zonesLoader.loadIndividualZones(); + + loadIndividualZones.forEach(this::addZonesToDb); + + } catch (Exception e) { + + throw new ServiceException(e); + } + + } + + + private void addZonesToDb(Map zonesMap) throws RuntimeException { + + try { + + for (Map.Entry entry : zonesMap.entrySet()) { + String key = entry.getKey(); + Zone value = entry.getValue(); + + if(value.getDescriptions()==null) { + LOGGER.warn("This zone " + key + " has no descriptions"); + continue; + } + + List zoneDescriptions = value.getDescriptions(); + value.setDescriptons(null); + + zoneService.create(value); + + for(ZoneDescription description : zoneDescriptions) { + description.setZone(value); + zoneService.addDescription(value, description); + } + } + + }catch(Exception e) { + LOGGER.error("An error occured while loading zones",e); + + } + + } + + private void createLanguages() throws ServiceException { + LOGGER.info(String.format("%s : Populating Languages ", name)); + for(String code : SchemaConstant.LANGUAGE_ISO_CODE) { + Language language = new Language(code); + languageService.create(language); + } + } + + private void createMerchant() throws ServiceException { + LOGGER.info(String.format("%s : Creating merchant ", name)); + + Date date = new Date(System.currentTimeMillis()); + + Language en = languageService.getByCode("en"); + Country ca = countryService.getByCode("CA"); + Currency currency = currencyService.getByCode("CAD"); + Zone qc = zoneService.getByCode("QC"); + + List supportedLanguages = new ArrayList(); + supportedLanguages.add(en); + + //create a merchant + MerchantStore store = new MerchantStore(); + store.setCountry(ca); + store.setCurrency(currency); + store.setDefaultLanguage(en); + store.setInBusinessSince(date); + store.setZone(qc); + store.setStorename("Default store"); + store.setStorephone("888-888-8888"); + store.setCode(MerchantStore.DEFAULT_STORE); + store.setStorecity("My city"); + store.setStoreaddress("1234 Street address"); + store.setStorepostalcode("H2H-2H2"); + store.setStoreEmailAddress("john@test.com"); + store.setDomainName("localhost:8080"); + store.setStoreTemplate("december"); + store.setRetailer(true); + store.setLanguages(supportedLanguages); + + merchantService.create(store); + + + TaxClass taxclass = new TaxClass(TaxClass.DEFAULT_TAX_CLASS); + taxclass.setMerchantStore(store); + + taxClassService.create(taxclass); + + //create default manufacturer + Manufacturer defaultManufacturer = new Manufacturer(); + defaultManufacturer.setCode("DEFAULT"); + defaultManufacturer.setMerchantStore(store); + + ManufacturerDescription manufacturerDescription = new ManufacturerDescription(); + manufacturerDescription.setLanguage(en); + manufacturerDescription.setName("DEFAULT"); + manufacturerDescription.setManufacturer(defaultManufacturer); + manufacturerDescription.setDescription("DEFAULT"); + defaultManufacturer.getDescriptions().add(manufacturerDescription); + + manufacturerService.create(defaultManufacturer); + + Optin newsletter = new Optin(); + newsletter.setCode(OptinType.NEWSLETTER.name()); + newsletter.setMerchant(store); + newsletter.setOptinType(OptinType.NEWSLETTER); + optinService.create(newsletter); + + + } + + private void createModules() throws ServiceException { + + try { + + List modules = modulesLoader.loadIntegrationModules("reference/integrationmodules.json"); + for (IntegrationModule entry : modules) { + moduleConfigurationService.create(entry); + } + + + } catch (Exception e) { + throw new ServiceException(e); + } + + + } + + private void createSubReferences() throws ServiceException { + + LOGGER.info(String.format("%s : Loading catalog sub references ", name)); + + + ProductType productType = new ProductType(); + productType.setCode(ProductType.GENERAL_TYPE); + productTypeService.create(productType); + + + + + } + + + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/reference/language/LanguageService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/language/LanguageService.java new file mode 100755 index 0000000000..f3b45d1282 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/language/LanguageService.java @@ -0,0 +1,25 @@ +package com.salesmanager.core.business.services.reference.language; + +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +public interface LanguageService extends SalesManagerEntityService { + + Language getByCode(String code) throws ServiceException; + + Map getLanguagesMap() throws ServiceException; + + List getLanguages() throws ServiceException; + + Locale toLocale(Language language, MerchantStore store); + + Language toLanguage(Locale locale); + + Language defaultLanguage(); +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/reference/language/LanguageServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/language/LanguageServiceImpl.java new file mode 100755 index 0000000000..62aab51d6a --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/language/LanguageServiceImpl.java @@ -0,0 +1,127 @@ +package com.salesmanager.core.business.services.reference.language; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.reference.language.LanguageRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.business.utils.CacheUtils; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +/** + * https://samerabdelkafi.wordpress.com/2014/05/29/spring-data-jpa/ + * @author c.samson + * + */ + +@Service("languageService") +public class LanguageServiceImpl extends SalesManagerEntityServiceImpl + implements LanguageService { + + private static final Logger LOGGER = LoggerFactory.getLogger(LanguageServiceImpl.class); + + @Inject + private CacheUtils cache; + + private LanguageRepository languageRepository; + + @Inject + public LanguageServiceImpl(LanguageRepository languageRepository) { + super(languageRepository); + this.languageRepository = languageRepository; + } + + + @Override + @Cacheable("languageByCode") + public Language getByCode(String code) throws ServiceException { + return languageRepository.findByCode(code); + } + + @Override + public Locale toLocale(Language language, MerchantStore store) { + + if(store != null) { + + String countryCode = store.getCountry().getIsoCode(); + + return new Locale(language.getCode(), countryCode); + + } else { + + return new Locale(language.getCode()); + } + } + + @Override + public Language toLanguage(Locale locale) { + Language language = null; + try { + language = getLanguagesMap().get(locale.getLanguage()); + } catch (Exception e) { + LOGGER.error("Cannot convert locale " + locale.getLanguage() + " to language"); + } + if(language == null) { + language = new Language(Constants.DEFAULT_LANGUAGE); + } + return language; + + } + + @Override + public Map getLanguagesMap() throws ServiceException { + + List langs = this.getLanguages(); + Map returnMap = new LinkedHashMap(); + + for(Language lang : langs) { + returnMap.put(lang.getCode(), lang); + } + return returnMap; + + } + + + @Override + @SuppressWarnings("unchecked") + public List getLanguages() throws ServiceException { + + + List langs = null; + try { + + langs = (List) cache.getFromCache("LANGUAGES"); + if(langs==null) { + langs = this.list(); + + + cache.putInCache(langs, "LANGUAGES"); + } + + } catch (Exception e) { + LOGGER.error("getCountries()", e); + throw new ServiceException(e); + } + + return langs; + + } + + @Override + public Language defaultLanguage() { + return toLanguage(Locale.ENGLISH); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/reference/loader/ConfigurationModulesLoader.java b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/loader/ConfigurationModulesLoader.java new file mode 100755 index 0000000000..46a461296c --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/loader/ConfigurationModulesLoader.java @@ -0,0 +1,105 @@ +package com.salesmanager.core.business.services.reference.loader; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.system.IntegrationConfiguration; + +/** + * Loads all modules in the database + * @author c.samson + * + */ +public class ConfigurationModulesLoader { + + @SuppressWarnings("unused") + private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationModulesLoader.class); + + + + public static String toJSONString(Map configurations) throws Exception { + + StringBuilder jsonModules = new StringBuilder(); + jsonModules.append("["); + int count = 0; + for(Object key : configurations.keySet()) { + + String k = (String)key; + IntegrationConfiguration c = configurations.get(k); + + String jsonString = c.toJSONString(); + jsonModules.append(jsonString); + + count ++; + if(count loadIntegrationConfigurations(String value) throws Exception { + + + Map modules = new HashMap(); + + ObjectMapper mapper = new ObjectMapper(); + + try { + + + Map[] objects = mapper.readValue(value, Map[].class); + + for (Map object : objects) { + + + IntegrationConfiguration configuration = new IntegrationConfiguration(); + + String moduleCode = (String) object.get("moduleCode"); + if (object.get("active") != null) { + configuration.setActive((Boolean) object.get("active")); + } + if (object.get("defaultSelected") != null) { + configuration.setDefaultSelected((Boolean) object.get("defaultSelected")); + } + if (object.get("environment") != null) { + configuration.setEnvironment((String) object.get("environment")); + } + configuration.setModuleCode(moduleCode); + + modules.put(moduleCode, configuration); + + if (object.get("integrationKeys") != null) { + Map confs = (Map) object.get("integrationKeys"); + configuration.setIntegrationKeys(confs); + } + + if (object.get("integrationKeys") != null) { + Map> options = (Map>) object.get("integrationOptions"); + configuration.setIntegrationOptions(options); + } + + + } + + return modules; + + } catch (Exception e) { + throw new ServiceException(e); + } + + + + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/reference/loader/IntegrationModulesLoader.java b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/loader/IntegrationModulesLoader.java new file mode 100755 index 0000000000..e5dcc1e82d --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/loader/IntegrationModulesLoader.java @@ -0,0 +1,190 @@ +package com.salesmanager.core.business.services.reference.loader; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.model.system.ModuleConfig; + +@Component +public class IntegrationModulesLoader { + + + private static final Logger LOGGER = LoggerFactory.getLogger(IntegrationModulesLoader.class); + + + public List loadIntegrationModules(String jsonFilePath) throws Exception { + + + List modules = new ArrayList(); + + ObjectMapper mapper = new ObjectMapper(); + + try { + + InputStream in = + this.getClass().getClassLoader().getResourceAsStream(jsonFilePath); + + + @SuppressWarnings("rawtypes") + Map[] objects = mapper.readValue(in, Map[].class); + + for (Map object : objects) { + + modules.add(this.loadModule(object)); + } + + return modules; + + } catch (Exception e) { + throw new ServiceException(e); + } + + + + + + + + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public IntegrationModule loadModule(Map object) throws Exception { + + ObjectMapper mapper = new ObjectMapper(); + IntegrationModule module = new IntegrationModule(); + module.setModule((String)object.get("module")); + module.setCode((String)object.get("code")); + module.setImage((String)object.get("image")); + + if(object.get("type")!=null) { + module.setType((String)object.get("type")); + } + + if(object.get("customModule")!=null) { + Object o = object.get("customModule"); + Boolean b = false; + if(o instanceof Boolean) { + b = (Boolean)object.get("customModule"); + } else { + try { + b = Boolean.valueOf((String) object.get("customModule")); + } catch(Exception e) { + LOGGER.error("Cannot cast " + o.getClass() + " tp a boolean value"); + } + } + module.setCustomModule(b); + } + //module.setRegions(regions) + if(object.get("details")!=null) { + + Map details = (Map)object.get("details"); + module.setDetails(details); + + //maintain the original json structure + StringBuilder detailsStructure = new StringBuilder(); + int count = 0; + detailsStructure.append("{"); + for(String key : details.keySet()) { + String jsonKeyString = mapper.writeValueAsString(key); + detailsStructure.append(jsonKeyString); + detailsStructure.append(":"); + String jsonValueString = mapper.writeValueAsString(details.get(key)); + detailsStructure.append(jsonValueString); + if(count<(details.size()-1)) { + detailsStructure.append(","); + } + count++; + } + detailsStructure.append("}"); + module.setConfigDetails(detailsStructure.toString()); + + } + + + List confs = (List)object.get("configuration"); + + //convert to json + + + + if(confs!=null) { + StringBuilder configString = new StringBuilder(); + configString.append("["); + Map moduleConfigs = new HashMap(); + int count=0; + for(Object oo : confs) { + + Map values = (Map)oo; + + String env = (String)values.get("env"); + + ModuleConfig config = new ModuleConfig(); + config.setScheme((String)values.get("scheme")); + config.setHost((String)values.get("host")); + config.setPort((String)values.get("port")); + config.setUri((String)values.get("uri")); + config.setEnv((String)values.get("env")); + if(values.get("config1") !=null) { + config.setConfig1((String)values.get("config1")); + } + if(values.get("config2") !=null) { + config.setConfig2((String)values.get("config2")); + } + + String jsonConfigString = mapper.writeValueAsString(config); + configString.append(jsonConfigString); + + moduleConfigs.put(env, config); + + if(count<(confs.size()-1)) { + configString.append(","); + } + count++; + + + } + configString.append("]"); + module.setConfiguration(configString.toString()); + module.setModuleConfigs(moduleConfigs); + } + + List regions = (List)object.get("regions"); + if(regions!=null) { + + + StringBuilder configString = new StringBuilder(); + configString.append("["); + int count=0; + for(String region : regions) { + + module.getRegionsSet().add(region); + String jsonConfigString = mapper.writeValueAsString(region); + configString.append(jsonConfigString); + + if(count<(regions.size()-1)) { + configString.append(","); + } + count++; + + } + configString.append("]"); + module.setRegions(configString.toString()); + + } + + return module; + + + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/reference/loader/ZonesLoader.java b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/loader/ZonesLoader.java new file mode 100755 index 0000000000..c9d03f066f --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/loader/ZonesLoader.java @@ -0,0 +1,295 @@ +package com.salesmanager.core.business.services.reference.loader; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.core.model.reference.zone.ZoneDescription; + +/** + * Drop files in reference/zones with following format + * + * _.json All lower cases + * + * @author carlsamson + * + */ +@Component +public class ZonesLoader { + + private static final Logger LOGGER = LoggerFactory.getLogger(ZonesLoader.class); + + @Inject + private LanguageService languageService; + + @Inject + private CountryService countryService; + + @Autowired + private ResourcePatternResolver resourceResolver; + + private static final String PATH = "classpath:/reference/zones/*.json"; + + private static final String ALL_REGIONS = "*"; + + // + @SuppressWarnings({ "rawtypes", "unchecked" }) + public List> loadIndividualZones() throws Exception { + + List> loadedZones = new ArrayList>(); + try { + + List files = geZoneFiles(PATH); + List languages = languageService.list(); + + ObjectMapper mapper = new ObjectMapper(); + + List countries = countryService.list(); + Map countriesMap = new HashMap(); + for (Country country : countries) { + countriesMap.put(country.getIsoCode(), country); + } + + Map zonesMap = new LinkedHashMap(); + Map> zonesDescriptionsMap = new LinkedHashMap>(); + Map zonesMark = new LinkedHashMap(); + + // load files individually + for (Resource resource : files) { + InputStream in = resource.getInputStream(); + if(in == null) { + continue; + } + Map data = mapper.readValue(in, Map.class); + + if(resource.getFilename().contains("_")) { + for (Language l : languages) { + if (resource.getFilename().contains("_" + l.getCode())) {// lead for this + // language + List langList = (List) data.get(l.getCode()); + if (langList != null) { + /** + * submethod + */ + for (Object z : langList) { + Map e = (Map) z; + mapZone(l, zonesDescriptionsMap, countriesMap, zonesMap, zonesMark, e); + } + } + } + } + } else { + List langList = (List) data.get(ALL_REGIONS); + if (langList != null) { + /** + * submethod + */ + for (Language l : languages) { + for (Object z : langList) { + Map e = (Map) z; + mapZone(l, zonesDescriptionsMap, countriesMap, zonesMap, zonesMark, e); + } + } + } + } + + for (Map.Entry entry : zonesMap.entrySet()) { + String key = entry.getKey(); + Zone value = entry.getValue(); + + // get descriptions + List descriptions = zonesDescriptionsMap.get(key); + if (descriptions != null) { + value.setDescriptons(descriptions); + } + } + + loadedZones.add(zonesMap); + } + return loadedZones; + + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + + private InputStream loadFileContent(String fileName) throws Exception { + return this.getClass().getClassLoader().getResourceAsStream("classpath:/reference/zones/" + fileName); + } + + public Map loadZones(String jsonFilePath) throws Exception { + + List languages = languageService.list(); + + List countries = countryService.list(); + Map countriesMap = new HashMap(); + for (Country country : countries) { + + countriesMap.put(country.getIsoCode(), country); + + } + + ObjectMapper mapper = new ObjectMapper(); + + try { + + InputStream in = this.getClass().getClassLoader().getResourceAsStream(jsonFilePath); + + @SuppressWarnings("unchecked") + Map data = mapper.readValue(in, Map.class); + + Map zonesMap = new HashMap(); + Map> zonesDescriptionsMap = new HashMap>(); + Map zonesMark = new HashMap(); + + for (Language l : languages) { + @SuppressWarnings("rawtypes") + List langList = (List) data.get(l.getCode()); + if (langList != null) { + /** + * submethod + */ + for (Object z : langList) { + @SuppressWarnings("unchecked") + Map e = (Map) z; + this.mapZone(l, zonesDescriptionsMap, countriesMap, zonesMap, zonesMark, e); + + /** + * String zoneCode = e.get("zoneCode"); ZoneDescription + * zoneDescription = new ZoneDescription(); + * zoneDescription.setLanguage(l); + * zoneDescription.setName(e.get("zoneName")); Zone zone + * = null; List descriptions = null; if + * (!zonesMap.containsKey(zoneCode)) { zone = new + * Zone(); Country country = + * countriesMap.get(e.get("countryCode")); if (country + * == null) { LOGGER.warn("Country is null for " + + * zoneCode + " and country code " + + * e.get("countryCode")); continue; } + * zone.setCountry(country); zonesMap.put(zoneCode, + * zone); zone.setCode(zoneCode); + * + * } + * + * if (zonesMark.containsKey(l.getCode() + "_" + + * zoneCode)) { LOGGER.warn("This zone seems to be a + * duplicate ! " + zoneCode + " and language code " + + * l.getCode()); continue; } + * + * zonesMark.put(l.getCode() + "_" + zoneCode, + * l.getCode() + "_" + zoneCode); + * + * if (zonesDescriptionsMap.containsKey(zoneCode)) { + * descriptions = zonesDescriptionsMap.get(zoneCode); } + * else { descriptions = new + * ArrayList(); + * zonesDescriptionsMap.put(zoneCode, descriptions); } + * + * descriptions.add(zoneDescription); + **/ + + } + } + + } + + for (Map.Entry entry : zonesMap.entrySet()) { + String key = entry.getKey(); + Zone value = entry.getValue(); + + // get descriptions + List descriptions = zonesDescriptionsMap.get(key); + if (descriptions != null) { + value.setDescriptons(descriptions); + } + } + + return zonesMap; + + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + // internal complex mapping stuff, don't try this at home ... + private void mapZone(Language l, Map> zonesDescriptionsMap, + Map countriesMap, Map zonesMap, Map zonesMark, + Map list) { + + String zoneCode = list.get("zoneCode"); + ZoneDescription zoneDescription = new ZoneDescription(); + zoneDescription.setLanguage(l); + zoneDescription.setName(list.get("zoneName")); + Zone zone = null; + List descriptions = null; + if (!zonesMap.containsKey(zoneCode)) { + zone = new Zone(); + Country country = countriesMap.get(list.get("countryCode")); + if (country == null) { + LOGGER.warn("Country is null for " + zoneCode + " and country code " + list.get("countryCode")); + return; + } + zone.setCountry(country); + zone.setCode(zoneCode); + zonesMap.put(zoneCode, zone); + + + } + + if (zonesMark.containsKey(l.getCode() + "_" + zoneCode)) { + LOGGER.warn("This zone seems to be a duplicate ! " + zoneCode + " and language code " + l.getCode()); + return; + } + + zonesMark.put(l.getCode() + "_" + zoneCode, l.getCode() + "_" + zoneCode); + + if (zonesDescriptionsMap.containsKey(zoneCode)) { + descriptions = zonesDescriptionsMap.get(zoneCode); + } else { + descriptions = new ArrayList(); + zonesDescriptionsMap.put(zoneCode, descriptions); + } + + descriptions.add(zoneDescription); + + } + + private List geZoneFiles(String path) throws IOException { + Resource[] resources =resourceResolver.getResources(PATH); + + List files = new ArrayList<>(); + Collections.addAll(files, resources); + return files; + + } + + + + + +} + diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/reference/zone/ZoneService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/zone/ZoneService.java new file mode 100755 index 0000000000..9188c1c8ab --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/zone/ZoneService.java @@ -0,0 +1,27 @@ +package com.salesmanager.core.business.services.reference.zone; + +import java.util.List; +import java.util.Map; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.core.model.reference.zone.ZoneDescription; + +public interface ZoneService extends SalesManagerEntityService { + + Zone getByCode(String code); + + void addDescription(Zone zone, ZoneDescription description) throws ServiceException; + + List getZones(Country country, Language language) + throws ServiceException; + + Map getZones(Language language) throws ServiceException; + + List getZones(String countryCode, Language language) throws ServiceException; + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/reference/zone/ZoneServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/zone/ZoneServiceImpl.java new file mode 100755 index 0000000000..e6c966192d --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/zone/ZoneServiceImpl.java @@ -0,0 +1,181 @@ +package com.salesmanager.core.business.services.reference.zone; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.reference.zone.ZoneRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.business.utils.CacheUtils; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.core.model.reference.zone.ZoneDescription; + +@Service("zoneService") +public class ZoneServiceImpl extends SalesManagerEntityServiceImpl implements + ZoneService { + + private final static String ZONE_CACHE_PREFIX = "ZONES_"; + + private ZoneRepository zoneRepository; + + @Inject + private CacheUtils cache; + + private static final Logger LOGGER = LoggerFactory.getLogger(ZoneServiceImpl.class); + + @Inject + public ZoneServiceImpl(ZoneRepository zoneRepository) { + super(zoneRepository); + this.zoneRepository = zoneRepository; + } + + @Override + @Cacheable("zoneByCode") + public Zone getByCode(String code) { + return zoneRepository.findByCode(code); + } + + @Override + public void addDescription(Zone zone, ZoneDescription description) throws ServiceException { + if (zone.getDescriptions()!=null) { + if(!zone.getDescriptions().contains(description)) { + zone.getDescriptions().add(description); + update(zone); + } + } else { + List descriptions = new ArrayList(); + descriptions.add(description); + zone.setDescriptons(descriptions); + update(zone); + } + } + + @SuppressWarnings("unchecked") + @Override + public List getZones(Country country, Language language) throws ServiceException { + + //Validate.notNull(country,"Country cannot be null"); + Validate.notNull(language,"Language cannot be null"); + + List zones = null; + try { + + String countryCode = Constants.DEFAULT_COUNTRY; + if(country!=null) { + countryCode = country.getIsoCode(); + } + + String cacheKey = ZONE_CACHE_PREFIX + countryCode + Constants.UNDERSCORE + language.getCode(); + + zones = (List) cache.getFromCache(cacheKey); + + + + if(zones==null) { + + zones = zoneRepository.listByLanguageAndCountry(countryCode, language.getId()); + + //set names + for(Zone zone : zones) { + ZoneDescription description = zone.getDescriptions().get(0); + zone.setName(description.getName()); + + } + cache.putInCache(zones, cacheKey); + } + + } catch (Exception e) { + LOGGER.error("getZones()", e); + } + return zones; + + + } + + @SuppressWarnings("unchecked") + @Override + public List getZones(String countryCode, Language language) throws ServiceException { + + Validate.notNull(countryCode,"countryCode cannot be null"); + Validate.notNull(language,"Language cannot be null"); + + List zones = null; + try { + + + String cacheKey = ZONE_CACHE_PREFIX + countryCode + Constants.UNDERSCORE + language.getCode(); + + zones = (List) cache.getFromCache(cacheKey); + + + + if(zones==null) { + + zones = zoneRepository.listByLanguageAndCountry(countryCode, language.getId()); + + //set names + for(Zone zone : zones) { + ZoneDescription description = zone.getDescriptions().get(0); + zone.setName(description.getName()); + + } + cache.putInCache(zones, cacheKey); + } + + } catch (Exception e) { + LOGGER.error("getZones()", e); + } + return zones; + + + } + + @Override + @SuppressWarnings("unchecked") + public Map getZones(Language language) throws ServiceException { + + Map zones = null; + try { + + String cacheKey = ZONE_CACHE_PREFIX + language.getCode(); + + zones = (Map) cache.getFromCache(cacheKey); + + + + if(zones==null) { + zones = new HashMap(); + List zns = zoneRepository.listByLanguage(language.getId()); + + //set names + for(Zone zone : zns) { + ZoneDescription description = zone.getDescriptions().get(0); + zone.setName(description.getName()); + zones.put(zone.getCode(), zone); + + } + cache.putInCache(zones, cacheKey); + } + + } catch (Exception e) { + LOGGER.error("getZones()", e); + } + return zones; + + + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/reference/zone/ZoneTransient.java b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/zone/ZoneTransient.java new file mode 100755 index 0000000000..9790b59d30 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/reference/zone/ZoneTransient.java @@ -0,0 +1,28 @@ +package com.salesmanager.core.business.services.reference.zone; + +public class ZoneTransient { + + private String zoneCode; + private String zoneName; + private String countryCode; + + public String getZoneCode() { + return zoneCode; + } + public void setZoneCode(String zoneCode) { + this.zoneCode = zoneCode; + } + public String getZoneName() { + return zoneName; + } + public void setZoneName(String zoneName) { + this.zoneName = zoneName; + } + public String getCountryCode() { + return countryCode; + } + public void setCountryCode(String countryCode) { + this.countryCode = countryCode; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/search/SearchService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/search/SearchService.java new file mode 100755 index 0000000000..479f07f488 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/search/SearchService.java @@ -0,0 +1,49 @@ +package com.salesmanager.core.business.services.search; + +import java.util.Optional; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.merchant.MerchantStore; + +import modules.commons.search.request.Document; +import modules.commons.search.request.SearchRequest; +import modules.commons.search.request.SearchResponse; + +public interface SearchService { + + /** + * The indexing service for products. The index service must be invoked when a product is + * created or updated + * @param store + * @param product + * @throws ServiceException + */ + void index(MerchantStore store, Product product) throws ServiceException; + + /** + * Deletes a document in the appropriate language. Must be invoked when a product is deleted + * @param store + * @param product + * @throws ServiceException + */ + void deleteDocument(MerchantStore store, Product product) + throws ServiceException; + + /** + * Similar keywords based on a a series of characters. Used in the auto-complete + */ + SearchResponse searchKeywords(MerchantStore store, String language, SearchRequest search, int entriesCount) throws ServiceException; + + /** + * Search products based on user entry + */ + + SearchResponse search(MerchantStore store, String language, SearchRequest search, + int entriesCount, int startIndex) throws ServiceException; + + + Optional getDocument(String language, MerchantStore store, Long id) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/search/SearchServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/search/SearchServiceImpl.java new file mode 100755 index 0000000000..f4293979cd --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/search/SearchServiceImpl.java @@ -0,0 +1,519 @@ +package com.salesmanager.core.business.services.search; + +import java.io.File; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.jsoup.helper.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.configuration.ApplicationSearchConfiguration; +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.inventory.ProductInventoryService; +import com.salesmanager.core.business.utils.CoreConfiguration; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.category.CategoryDescription; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValueDescription; +import com.salesmanager.core.model.catalog.product.description.ProductDescription; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.catalog.product.inventory.ProductInventory; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.catalog.product.manufacturer.ManufacturerDescription; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.merchant.MerchantStore; + +import modules.commons.search.SearchModule; +import modules.commons.search.configuration.SearchConfiguration; +import modules.commons.search.request.Document; +import modules.commons.search.request.IndexItem; +import modules.commons.search.request.RequestOptions; +import modules.commons.search.request.SearchRequest; +import modules.commons.search.request.SearchResponse; + +@Service("productSearchService") +@EnableConfigurationProperties(value = ApplicationSearchConfiguration.class) +public class SearchServiceImpl implements com.salesmanager.core.business.services.search.SearchService { + + + @Value("${search.noindex:false}")//skip indexing process + private boolean noIndex; + + private static final Logger LOGGER = LoggerFactory.getLogger(SearchServiceImpl.class); + + private final static String INDEX_PRODUCTS = "INDEX_PRODUCTS"; + + private final static String SETTINGS = "search/SETTINGS"; + + private final static String PRODUCT_MAPPING_DEFAULT = "search/MAPPINGS.json"; + + private final static String QTY = "QTY"; + private final static String PRICE = "PRICE"; + private final static String DISCOUNT_PRICE = "DISCOUNT"; + private final static String SKU = "SKU"; + private final static String VSKU = "VSKU"; + + + /** + * TODO properties file + */ + + private final static String KEYWORDS_MAPPING_DEFAULT = "{\"properties\":" + + " {\n\"id\": {\n" + + " \"type\": \"long\"\n" + + " }\n" + + " }\n" + + " }"; + + + + @Inject + private CoreConfiguration configuration; + + @Autowired + private ApplicationSearchConfiguration applicationSearchConfiguration; + + @Autowired + private ProductInventoryService productInventoryService; + + @Autowired(required = false) + private SearchModule searchModule; + + @PostConstruct + public void init() throws Exception { + + /** + * Configure search module + */ + + if (searchModule != null && !noIndex) { + + SearchConfiguration searchConfiguration = config(); + try { + searchModule.configure(searchConfiguration); + } catch (Exception e) { + LOGGER.error("SearchModule cannot be configured [" + e.getMessage() + "]", e); + } + } + } + + public void index(MerchantStore store, Product product) throws ServiceException { + + Validate.notNull(product.getId(), "Product.id cannot be null"); + + if (configuration.getProperty(INDEX_PRODUCTS) == null + || configuration.getProperty(INDEX_PRODUCTS).equals(Constants.FALSE) || searchModule == null) { + return; + } + + List languages = languages(product); + + // existing documents + List documents; + List> variants = null; + try { + documents = document(product.getId(), languages, RequestOptions.DO_NOT_FAIL_ON_NOT_FOUND); + + if (!CollectionUtils.isEmpty(product.getVariants())) { + variants = new ArrayList>(); + variants = product.getVariants().stream().map(i -> variants(i)).collect(Collectors.toList()); + } + + if (!CollectionUtils.isEmpty(documents)) { + if (documents.iterator().next() != null) { + searchModule.delete(languages, product.getId()); + } + } + + + } catch (Exception e) { + throw new ServiceException(e); + } + + Set descriptions = product.getDescriptions(); + + for (ProductDescription description : descriptions) { + indexProduct(store, description, product, variants); + } + + } + + private List document(Long id, List languages, RequestOptions options) throws Exception { + List> documents = null; + try { + documents = searchModule.getDocument(id, languages, options); + } catch(Exception e) { + e.printStackTrace(); + } + + for(Optional d : documents) { + if(d == null) {//not allowed + return Collections.emptyList(); + } + } + + List filteredList = documents.stream().filter(Optional::isPresent).map(Optional::get) + .collect(Collectors.toList()); + + return filteredList; + + } + + private void indexProduct(MerchantStore store, ProductDescription description, Product product, + List> variants) throws ServiceException { + + try { + ProductImage image = null; + if (!CollectionUtils.isEmpty(product.getImages())) { + image = product.getImages().stream().filter(i -> i.isDefaultImage()).findFirst() + .orElse(product.getImages().iterator().next()); + } + + /** + * Inventory + */ + + /** + * SKU, QTY, PRICE, DISCOUNT + */ + + List> itemInventory = new ArrayList>(); + + itemInventory.add(inventory(product)); + + if (!CollectionUtils.isEmpty(product.getVariants())) { + for(ProductVariant variant : product.getVariants()) { + itemInventory.add(inventory(variant)); + } + } + + IndexItem item = new IndexItem(); + item.setId(product.getId()); + item.setStore(store.getCode().toLowerCase()); + item.setDescription(description.getDescription()); + item.setName(description.getName()); + item.setInventory(itemInventory); + + + if (product.getManufacturer() != null) { + item.setBrand(manufacturer(product.getManufacturer(), description.getLanguage().getCode())); + } + + if (!CollectionUtils.isEmpty(product.getCategories())) { + item.setCategory( + category(product.getCategories().iterator().next(), description.getLanguage().getCode())); + } + + if (!CollectionUtils.isEmpty(product.getAttributes())) { + Map attributes = attributes(product, description.getLanguage().getCode()); + item.setAttributes(attributes); + } + + if (image != null) { + item.setImage(image.getProductImage()); + } + + if (product.getProductReviewAvg() != null) { + item.setReviews(product.getProductReviewAvg().toString()); + } + + if (!CollectionUtils.isEmpty(variants)) { + item.setVariants(variants); + } + + item.setLanguage(description.getLanguage().getCode()); + item.setLink(description.getSeUrl()); + + searchModule.index(item); + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + private SearchConfiguration config() throws Exception { + + SearchConfiguration config = new SearchConfiguration(); + config.setClusterName(applicationSearchConfiguration.getClusterName()); + config.setHosts(applicationSearchConfiguration.getHost()); + config.setCredentials(applicationSearchConfiguration.getCredentials()); + + config.setLanguages(applicationSearchConfiguration.getSearchLanguages()); + + config.getLanguages().stream().forEach(l -> { + try { + this.mappings(config,l); + } catch (Exception e) { + throw new IllegalStateException(e); + } + }); + config.getLanguages().stream().forEach(l -> { + try { + this.settings(config,l); + } catch (Exception e) { + throw new IllegalStateException(e); + } + }); + + + + /** + * The mapping + */ + /* + * config.getProductMappings().put("variants", "nested"); + * config.getProductMappings().put("attributes", "nested"); + * config.getProductMappings().put("brand", "keyword"); + * config.getProductMappings().put("store", "keyword"); + * config.getProductMappings().put("reviews", "keyword"); + * config.getProductMappings().put("image", "keyword"); + * config.getProductMappings().put("category", "text"); + * config.getProductMappings().put("name", "text"); + * config.getProductMappings().put("description", "text"); + * config.getProductMappings().put("price", "float"); + * config.getProductMappings().put("id", "long"); + + config.getKeywordsMappings().put("store", "keyword"); + */ + + return config; + + } + + private Map inventory(Product product) throws Exception { + + + /** + * Default inventory + */ + + ProductInventory inventory = productInventoryService.inventory(product); + + Map inventoryMap = new HashMap(); + inventoryMap.put(SKU, product.getSku()); + inventoryMap.put(QTY, String.valueOf(inventory.getQuantity())); + inventoryMap.put(PRICE, String.valueOf(inventory.getPrice().getStringPrice())); + if(inventory.getPrice().isDiscounted()) { + inventoryMap.put(DISCOUNT_PRICE, String.valueOf(inventory.getPrice().getStringDiscountedPrice())); + } + + + return inventoryMap; + } + + private Map inventory(ProductVariant product) throws Exception { + + + /** + * Default inventory + */ + + ProductInventory inventory = productInventoryService.inventory(product); + + Map inventoryMap = new HashMap(); + inventoryMap.put(SKU, product.getSku()); + inventoryMap.put(QTY, String.valueOf(inventory.getQuantity())); + inventoryMap.put(PRICE, String.valueOf(inventory.getPrice().getStringPrice())); + if(inventory.getPrice().isDiscounted()) { + inventoryMap.put(DISCOUNT_PRICE, String.valueOf(inventory.getPrice().getStringDiscountedPrice())); + } + + + return inventoryMap; + } + + private Map variants(ProductVariant variant) { + if (variant == null) + return null; + + Map variantMap = new HashMap(); + if (variant.getVariation() != null) { + String variantCode = variant.getVariation().getProductOption().getCode(); + String variantValueCode = variant.getVariation().getProductOptionValue().getCode(); + + variantMap.put(variantCode, variantValueCode); + + } + + + if (variant.getVariationValue() != null) { + String variantCode = variant.getVariationValue().getProductOption().getCode(); + String variantValueCode = variant.getVariationValue().getProductOptionValue().getCode(); + variantMap.put(variantCode, variantValueCode); + } + + if(!StringUtils.isBlank(variant.getSku())) { + variantMap.put(VSKU, variant.getSku()); + } + + + + return variantMap; + + } + + @Override + public void deleteDocument(MerchantStore store, Product product) throws ServiceException { + + if (configuration.getProperty(INDEX_PRODUCTS) == null + || configuration.getProperty(INDEX_PRODUCTS).equals(Constants.FALSE) || searchModule == null) { + return; + } + + List languages = languages(product); + + try { + searchModule.delete(languages, product.getId()); + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + @Override + public SearchResponse searchKeywords(MerchantStore store, String language, SearchRequest search, int entriesCount) + throws ServiceException { + + if (configuration.getProperty(INDEX_PRODUCTS) == null + || configuration.getProperty(INDEX_PRODUCTS).equals(Constants.FALSE) || searchModule == null) { + return null; + } + + try { + return searchModule.searchKeywords(search); + } catch (Exception e) { + throw new ServiceException(e); + } + } + + @Override + public SearchResponse search(MerchantStore store, String language, SearchRequest search, int entriesCount, + int startIndex) throws ServiceException { + + if (configuration.getProperty(INDEX_PRODUCTS) == null + || configuration.getProperty(INDEX_PRODUCTS).equals(Constants.FALSE) || searchModule == null) { + return null; + } + + try { + return searchModule.searchProducts(search); + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + @Override + public Optional getDocument(String language, MerchantStore store, Long productId) + throws ServiceException { + if (configuration.getProperty(INDEX_PRODUCTS) == null + || configuration.getProperty(INDEX_PRODUCTS).equals(Constants.FALSE) || searchModule == null) { + return null; + } + + try { + return searchModule.getDocument(productId, language, RequestOptions.DEFAULT); + } catch (Exception e) { + throw new ServiceException(e); + } + } + + private List languages(Product product) { + return product.getDescriptions().stream().map(d -> d.getLanguage().getCode()).collect(Collectors.toList()); + } + + private String manufacturer(Manufacturer manufacturer, String language) { + ManufacturerDescription description = manufacturer.getDescriptions().stream() + .filter(d -> d.getLanguage().getCode().equals(language)).findFirst().get(); + return description.getName(); + } + + private String category(Category category, String language) { + CategoryDescription description = category.getDescriptions().stream() + .filter(d -> d.getLanguage().getCode().equals(language)).findFirst().get(); + return description.getName(); + } + + private Map attributes(Product product, String language) { + + /** + * ProductAttribute ProductOption ProductOptionValue + */ + + Map allAttributes = new HashMap(); + + for (ProductAttribute attribute : product.getAttributes()) { + Map attr = attribute(attribute, language); + allAttributes.putAll(attr); + } + + return allAttributes; + + } + + private Map attribute(ProductAttribute attribute, String language) { + Map attributeValue = new HashMap(); + + ProductOptionDescription optionDescription = attribute.getProductOption().getDescriptions().stream() + .filter(a -> a.getLanguage().getCode().equals(language)).findFirst().get(); + + ProductOptionValueDescription value = attribute.getProductOptionValue().getDescriptions().stream() + .filter(a -> a.getLanguage().getCode().equals(language)).findFirst().get(); + + attributeValue.put(optionDescription.getName(), value.getName()); + + return attributeValue; + } + + private void settings(SearchConfiguration config, String language) throws Exception{ + Validate.notEmpty(language, "Configuration requires language"); + String settings = loadClassPathResource(SETTINGS + "_DEFAULT.json"); + //specific settings + if(language.equals("en")) { + settings = loadClassPathResource(SETTINGS+ "_" + language +".json"); + } + + config.getSettings().put(language, settings); + + } + + private void mappings(SearchConfiguration config, String language) throws Exception { + Validate.notEmpty(language, "Configuration requires language"); + + + config.getProductMappings().put(language, loadClassPathResource(PRODUCT_MAPPING_DEFAULT)); + config.getKeywordsMappings().put(language, KEYWORDS_MAPPING_DEFAULT); + + } + + public String loadClassPathResource(String file) throws Exception { + Resource res = new ClassPathResource(file); + File f = res.getFile(); + + return new String( + Files.readAllBytes(f.toPath())); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingOriginService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingOriginService.java new file mode 100755 index 0000000000..ee469c45a1 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingOriginService.java @@ -0,0 +1,19 @@ +package com.salesmanager.core.business.services.shipping; + +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.shipping.ShippingOrigin; + +/** + * ShippingOrigin object if different from MerchantStore address. + * Can be managed through this service. + * @author carlsamson + * + */ +public interface ShippingOriginService extends SalesManagerEntityService { + + ShippingOrigin getByStore(MerchantStore store); + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingOriginServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingOriginServiceImpl.java new file mode 100755 index 0000000000..f7125ebf78 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingOriginServiceImpl.java @@ -0,0 +1,39 @@ +package com.salesmanager.core.business.services.shipping; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.repositories.shipping.ShippingOriginRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.shipping.ShippingOrigin; + + + +@Service("shippingOriginService") +public class ShippingOriginServiceImpl extends SalesManagerEntityServiceImpl implements ShippingOriginService { + + private static final Logger LOGGER = LoggerFactory.getLogger(ShippingOriginServiceImpl.class); + + private ShippingOriginRepository shippingOriginRepository; + + + + @Inject + public ShippingOriginServiceImpl(ShippingOriginRepository shippingOriginRepository) { + super(shippingOriginRepository); + this.shippingOriginRepository = shippingOriginRepository; + } + + + @Override + public ShippingOrigin getByStore(MerchantStore store) { + // TODO Auto-generated method stub + return shippingOriginRepository.findByStore(store.getId()); + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingQuoteService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingQuoteService.java new file mode 100755 index 0000000000..ea13cd1bf3 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingQuoteService.java @@ -0,0 +1,38 @@ +package com.salesmanager.core.business.services.shipping; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.shipping.Quote; +import com.salesmanager.core.model.shipping.ShippingSummary; + +import java.util.List; + +/** + * Saves and retrieves various shipping quotes done by the system + * @author c.samson + * + */ +public interface ShippingQuoteService extends SalesManagerEntityService { + + /** + * Find shipping quotes by Order + * @param order + * @return + * @throws ServiceException + */ + List findByOrder(Order order) throws ServiceException; + + + /** + * Each quote asked for a given shopping cart creates individual Quote object + * in the table ShippingQuote. This method allows the creation of a ShippingSummary + * object to work with in the services and in the api. + * @param quoteId + * @return + * @throws ServiceException + */ + ShippingSummary getShippingSummary(Long quoteId, MerchantStore store) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingQuoteServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingQuoteServiceImpl.java new file mode 100755 index 0000000000..160eaaf3df --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingQuoteServiceImpl.java @@ -0,0 +1,78 @@ +package com.salesmanager.core.business.services.shipping; + +import java.util.List; + +import javax.inject.Inject; + +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.shipping.ShippingQuoteRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.shipping.Quote; +import com.salesmanager.core.model.shipping.ShippingSummary; + +@Service("shippingQuoteService") +public class ShippingQuoteServiceImpl extends SalesManagerEntityServiceImpl implements ShippingQuoteService { + + + private static final Logger LOGGER = LoggerFactory.getLogger(ShippingQuoteServiceImpl.class); + + private ShippingQuoteRepository shippingQuoteRepository; + + @Inject + private ShippingService shippingService; + + @Inject + public ShippingQuoteServiceImpl(ShippingQuoteRepository repository) { + super(repository); + this.shippingQuoteRepository = repository; + // TODO Auto-generated constructor stub + } + + @Override + public List findByOrder(Order order) throws ServiceException { + Validate.notNull(order,"Order cannot be null"); + return this.shippingQuoteRepository.findByOrder(order.getId()); + } + + @Override + public ShippingSummary getShippingSummary(Long quoteId, MerchantStore store) throws ServiceException { + + Validate.notNull(quoteId,"quoteId must not be null"); + + Quote q = shippingQuoteRepository.getOne(quoteId); + + + ShippingSummary quote = null; + + if(q != null) { + + quote = new ShippingSummary(); + quote.setDeliveryAddress(q.getDelivery()); + quote.setShipping(q.getPrice()); + quote.setShippingModule(q.getModule()); + quote.setShippingOption(q.getOptionName()); + quote.setShippingOptionCode(q.getOptionCode()); + quote.setHandling(q.getHandling()); + + if(shippingService.hasTaxOnShipping(store)) { + quote.setTaxOnShipping(true); + } + + + + } + + + return quote; + + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingService.java new file mode 100755 index 0000000000..bcf5fa5283 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingService.java @@ -0,0 +1,217 @@ +package com.salesmanager.core.business.services.shipping; + +import java.util.List; +import java.util.Map; + + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shipping.PackageDetails; +import com.salesmanager.core.model.shipping.ShippingConfiguration; +import com.salesmanager.core.model.shipping.ShippingMetaData; +import com.salesmanager.core.model.shipping.ShippingOption; +import com.salesmanager.core.model.shipping.ShippingProduct; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.model.shipping.ShippingSummary; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.model.system.CustomIntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; + + + +public interface ShippingService { + + /** + * Returns a list of supported countries (ship to country list) configured by merchant + * when the merchant configured shipping National and has saved a list of ship to country + * from the list + * @param store + * @return + * @throws ServiceException + */ + List getSupportedCountries(MerchantStore store) + throws ServiceException; + + void setSupportedCountries(MerchantStore store, + List countryCodes) throws ServiceException; + + /** + * Returns a list of available shipping modules + * @param store + * @return + * @throws ServiceException + */ + List getShippingMethods(MerchantStore store) + throws ServiceException; + + + /** + * Returns a list of configured shipping modules for a given merchant + * @param store + * @return + * @throws ServiceException + */ + Map getShippingModulesConfigured( + MerchantStore store) throws ServiceException; + + /** + * Adds a Shipping configuration + * @param configuration + * @param store + * @throws ServiceException + */ + void saveShippingQuoteModuleConfiguration(IntegrationConfiguration configuration, + MerchantStore store) throws ServiceException; + + /** + * ShippingType (NATIONAL, INTERNATIONSL) + * ShippingBasisType (SHIPPING, BILLING) + * ShippingPriceOptionType (ALL, LEAST, HIGHEST) + * Packages + * Handling + * @param store + * @return + * @throws ServiceException + */ + ShippingConfiguration getShippingConfiguration(MerchantStore store) + throws ServiceException; + + /** + * Saves ShippingConfiguration for a given MerchantStore + * @param shippingConfiguration + * @param store + * @throws ServiceException + */ + void saveShippingConfiguration(ShippingConfiguration shippingConfiguration, + MerchantStore store) throws ServiceException; + + void removeShippingQuoteModuleConfiguration(String moduleCode, + MerchantStore store) throws ServiceException; + + /** + * Provides detailed information on boxes that will be used + * when getting a ShippingQuote + * @param products + * @param store + * @return + * @throws ServiceException + */ + List getPackagesDetails(List products, + MerchantStore store) throws ServiceException; + + /** + * Get a list of ShippingQuote from a configured + * shipping gateway. The quotes are displayed to the end user so he can pick + * the ShippingOption he wants + * @param store + * @param shoppingCartId + * @param customer + * @param products + * @param language + * @return + * @throws ServiceException + */ + ShippingQuote getShippingQuote(Long shoppingCartId, MerchantStore store, Delivery delivery, + List products, Language language) + throws ServiceException; + + + /** + * Returns a shipping module configuration given a moduleCode + * @param moduleCode + * @param store + * @return + * @throws ServiceException + */ + IntegrationConfiguration getShippingConfiguration(String moduleCode, + MerchantStore store) throws ServiceException; + + /** + * Retrieves the custom configuration for a given module + * @param moduleCode + * @param store + * @return + * @throws ServiceException + */ + + + CustomIntegrationConfiguration getCustomShippingConfiguration( + String moduleCode, MerchantStore store) throws ServiceException; + + /** + * Weight based configuration + * @param moduleCode + * @param shippingConfiguration + * @param store + * @throws ServiceException + */ + void saveCustomShippingConfiguration(String moduleCode, + CustomIntegrationConfiguration shippingConfiguration, + MerchantStore store) throws ServiceException; + + /** + * Removes a custom shipping quote + * module + * @param moduleCode + * @param store + * @throws ServiceException + */ + void removeCustomShippingQuoteModuleConfiguration(String moduleCode, + MerchantStore store) throws ServiceException; + + /** + * The {@link ShippingSummary} is built from the ShippingOption the user has selected + * The ShippingSummary is used for order calculation + * @param store + * @param shippingQuote + * @param selectedShippingOption + * @return + * @throws ServiceException + */ + ShippingSummary getShippingSummary(MerchantStore store, ShippingQuote shippingQuote, + ShippingOption selectedShippingOption) throws ServiceException; + + /** + * Returns a list of supported countries (ship to country list) configured by merchant + * If the merchant configured shipping National, then only store country will be in the list + * If the merchant configured shipping International, then the list of accepted country is returned + * from the list + * @param store + * @param language + * @return + * @throws ServiceException + */ + List getShipToCountryList(MerchantStore store, Language language) + throws ServiceException; + + /** + * Determines if Shipping should be proposed to the customer + * @param items + * @param store + * @return + * @throws ServiceException + */ + boolean requiresShipping(List items, MerchantStore store) throws ServiceException; + + /** + * Returns shipping metadata and how shipping is configured for a given store + * @param store + * @return + * @throws ServiceException + */ + ShippingMetaData getShippingMetaData(MerchantStore store) throws ServiceException; + + /** + * Based on merchant configurations will return if tax must be calculated on shipping + * @param store + * @return + * @throws ServiceException + */ + boolean hasTaxOnShipping(MerchantStore store) throws ServiceException; + + +} \ No newline at end of file diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingServiceImpl.java new file mode 100755 index 0000000000..6d58fc3073 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/shipping/ShippingServiceImpl.java @@ -0,0 +1,962 @@ +package com.salesmanager.core.business.services.shipping; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; + +import javax.annotation.Resource; +import javax.inject.Inject; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.json.simple.JSONArray; +import org.json.simple.JSONValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.salesmanager.core.business.constants.ShippingConstants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.services.reference.loader.ConfigurationModulesLoader; +import com.salesmanager.core.business.services.system.MerchantConfigurationService; +import com.salesmanager.core.business.services.system.ModuleConfigurationService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.common.UserContext; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shipping.PackageDetails; +import com.salesmanager.core.model.shipping.Quote; +import com.salesmanager.core.model.shipping.ShippingConfiguration; +import com.salesmanager.core.model.shipping.ShippingMetaData; +import com.salesmanager.core.model.shipping.ShippingOption; +import com.salesmanager.core.model.shipping.ShippingOptionPriceType; +import com.salesmanager.core.model.shipping.ShippingOrigin; +import com.salesmanager.core.model.shipping.ShippingPackageType; +import com.salesmanager.core.model.shipping.ShippingProduct; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.model.shipping.ShippingSummary; +import com.salesmanager.core.model.shipping.ShippingType; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.model.system.CustomIntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.model.system.MerchantConfiguration; +import com.salesmanager.core.modules.integration.IntegrationException; +import com.salesmanager.core.modules.integration.shipping.model.Packaging; +import com.salesmanager.core.modules.integration.shipping.model.ShippingQuoteModule; +import com.salesmanager.core.modules.integration.shipping.model.ShippingQuotePrePostProcessModule; +import com.salesmanager.core.modules.utils.Encryption; + + +@Service("shippingService") +public class ShippingServiceImpl implements ShippingService { + + private static final Logger LOGGER = LoggerFactory.getLogger(ShippingServiceImpl.class); + + + private final static String SUPPORTED_COUNTRIES = "SUPPORTED_CNTR"; + private final static String SHIPPING_MODULES = "SHIPPING"; + private final static String SHIPPING_DISTANCE = "shippingDistanceModule"; + + + @Inject + private MerchantConfigurationService merchantConfigurationService; + + + @Inject + private PricingService pricingService; + + @Inject + private ModuleConfigurationService moduleConfigurationService; + + @Inject + private Packaging packaging; + + @Inject + private CountryService countryService; + + @Inject + private LanguageService languageService; + + @Inject + private Encryption encryption; + + @Inject + private ShippingOriginService shippingOriginService; + + @Inject + private ShippingQuoteService shippingQuoteService; + + @Inject + @Resource(name="shippingModules") + private Map shippingModules; + + //shipping pre-processors + @Inject + @Resource(name="shippingModulePreProcessors") + private List shippingModulePreProcessors; + + //shipping post-processors + @Inject + @Resource(name="shippingModulePostProcessors") + private List shippingModulePostProcessors; + + @Override + public ShippingConfiguration getShippingConfiguration(MerchantStore store) throws ServiceException { + + MerchantConfiguration configuration = merchantConfigurationService.getMerchantConfiguration(ShippingConstants.SHIPPING_CONFIGURATION, store); + + ShippingConfiguration shippingConfiguration = null; + + if(configuration!=null) { + String value = configuration.getValue(); + + ObjectMapper mapper = new ObjectMapper(); + try { + shippingConfiguration = mapper.readValue(value, ShippingConfiguration.class); + } catch(Exception e) { + throw new ServiceException("Cannot parse json string " + value); + } + } + return shippingConfiguration; + + } + + @Override + public IntegrationConfiguration getShippingConfiguration(String moduleCode, MerchantStore store) throws ServiceException { + + + Map configuredModules = getShippingModulesConfigured(store); + if(configuredModules!=null) { + for(String key : configuredModules.keySet()) { + if(key.equals(moduleCode)) { + return configuredModules.get(key); + } + } + } + + return null; + + } + + @Override + public CustomIntegrationConfiguration getCustomShippingConfiguration(String moduleCode, MerchantStore store) throws ServiceException { + + + ShippingQuoteModule quoteModule = shippingModules.get(moduleCode); + if(quoteModule==null) { + return null; + } + return quoteModule.getCustomModuleConfiguration(store); + + } + + @Override + public void saveShippingConfiguration(ShippingConfiguration shippingConfiguration, MerchantStore store) throws ServiceException { + + MerchantConfiguration configuration = merchantConfigurationService.getMerchantConfiguration(ShippingConstants.SHIPPING_CONFIGURATION, store); + + if(configuration==null) { + configuration = new MerchantConfiguration(); + configuration.setMerchantStore(store); + configuration.setKey(ShippingConstants.SHIPPING_CONFIGURATION); + } + + String value = shippingConfiguration.toJSONString(); + configuration.setValue(value); + merchantConfigurationService.saveOrUpdate(configuration); + + } + + @Override + public void saveCustomShippingConfiguration(String moduleCode, CustomIntegrationConfiguration shippingConfiguration, MerchantStore store) throws ServiceException { + + + ShippingQuoteModule quoteModule = shippingModules.get(moduleCode); + if(quoteModule==null) { + throw new ServiceException("Shipping module " + moduleCode + " does not exist"); + } + + String configurationValue = shippingConfiguration.toJSONString(); + + + try { + + MerchantConfiguration configuration = merchantConfigurationService.getMerchantConfiguration(moduleCode, store); + + if(configuration==null) { + + configuration = new MerchantConfiguration(); + configuration.setKey(moduleCode); + configuration.setMerchantStore(store); + } + configuration.setValue(configurationValue); + merchantConfigurationService.saveOrUpdate(configuration); + + } catch (Exception e) { + throw new IntegrationException(e); + } + + + + } + + + @Override + public List getShippingMethods(MerchantStore store) throws ServiceException { + + List modules = moduleConfigurationService.getIntegrationModules(SHIPPING_MODULES); + List returnModules = new ArrayList(); + + for(IntegrationModule module : modules) { + if(module.getRegionsSet().contains(store.getCountry().getIsoCode()) + || module.getRegionsSet().contains("*")) { + + returnModules.add(module); + } + } + + return returnModules; + } + + @Override + public void saveShippingQuoteModuleConfiguration(IntegrationConfiguration configuration, MerchantStore store) throws ServiceException { + + //validate entries + try { + + String moduleCode = configuration.getModuleCode(); + ShippingQuoteModule quoteModule = (ShippingQuoteModule)shippingModules.get(moduleCode); + if(quoteModule==null) { + throw new ServiceException("Shipping quote module " + moduleCode + " does not exist"); + } + quoteModule.validateModuleConfiguration(configuration, store); + + } catch (IntegrationException ie) { + throw ie; + } + + try { + Map modules = new HashMap(); + MerchantConfiguration merchantConfiguration = merchantConfigurationService.getMerchantConfiguration(SHIPPING_MODULES, store); + if(merchantConfiguration!=null) { + if(!StringUtils.isBlank(merchantConfiguration.getValue())) { + + String decrypted = encryption.decrypt(merchantConfiguration.getValue()); + modules = ConfigurationModulesLoader.loadIntegrationConfigurations(decrypted); + } + } else { + merchantConfiguration = new MerchantConfiguration(); + merchantConfiguration.setMerchantStore(store); + merchantConfiguration.setKey(SHIPPING_MODULES); + } + modules.put(configuration.getModuleCode(), configuration); + + String configs = ConfigurationModulesLoader.toJSONString(modules); + + String encrypted = encryption.encrypt(configs); + merchantConfiguration.setValue(encrypted); + merchantConfigurationService.saveOrUpdate(merchantConfiguration); + + } catch (Exception e) { + throw new ServiceException(e); + } + } + + + @Override + public void removeShippingQuoteModuleConfiguration(String moduleCode, MerchantStore store) throws ServiceException { + + + + try { + Map modules = new HashMap(); + MerchantConfiguration merchantConfiguration = merchantConfigurationService.getMerchantConfiguration(SHIPPING_MODULES, store); + if(merchantConfiguration!=null) { + if(!StringUtils.isBlank(merchantConfiguration.getValue())) { + String decrypted = encryption.decrypt(merchantConfiguration.getValue()); + modules = ConfigurationModulesLoader.loadIntegrationConfigurations(decrypted); + } + + modules.remove(moduleCode); + String configs = ConfigurationModulesLoader.toJSONString(modules); + String encrypted = encryption.encrypt(configs); + merchantConfiguration.setValue(encrypted); + merchantConfigurationService.saveOrUpdate(merchantConfiguration); + + + } + + MerchantConfiguration configuration = merchantConfigurationService.getMerchantConfiguration(moduleCode, store); + + if(configuration!=null) {//custom module + + merchantConfigurationService.delete(configuration); + } + + + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + @Override + public void removeCustomShippingQuoteModuleConfiguration(String moduleCode, MerchantStore store) throws ServiceException { + + + + try { + + removeShippingQuoteModuleConfiguration(moduleCode,store); + MerchantConfiguration merchantConfiguration = merchantConfigurationService.getMerchantConfiguration(moduleCode, store); + if(merchantConfiguration!=null) { + merchantConfigurationService.delete(merchantConfiguration); + } + + + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + @Override + public Map getShippingModulesConfigured(MerchantStore store) throws ServiceException { + try { + + + Map modules = new HashMap(); + MerchantConfiguration merchantConfiguration = merchantConfigurationService.getMerchantConfiguration(SHIPPING_MODULES, store); + if(merchantConfiguration!=null) { + if(!StringUtils.isBlank(merchantConfiguration.getValue())) { + String decrypted = encryption.decrypt(merchantConfiguration.getValue()); + modules = ConfigurationModulesLoader.loadIntegrationConfigurations(decrypted); + + } + } + return modules; + + + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + @Override + public ShippingSummary getShippingSummary(MerchantStore store, ShippingQuote shippingQuote, ShippingOption selectedShippingOption) throws ServiceException { + + ShippingSummary shippingSummary = new ShippingSummary(); + shippingSummary.setFreeShipping(shippingQuote.isFreeShipping()); + shippingSummary.setHandling(shippingQuote.getHandlingFees()); + shippingSummary.setShipping(selectedShippingOption.getOptionPrice()); + shippingSummary.setShippingModule(shippingQuote.getShippingModuleCode()); + shippingSummary.setShippingOption(selectedShippingOption.getDescription()); + + return shippingSummary; + } + + @Override + public ShippingQuote getShippingQuote(Long shoppingCartId, MerchantStore store, Delivery delivery, List products, Language language) throws ServiceException { + + + //ShippingConfiguration -> Global configuration of a given store + //IntegrationConfiguration -> Configuration of a given module + //IntegrationModule -> The concrete module as defined in integrationmodules.properties + + //delivery without postal code is accepted + Validate.notNull(store,"MerchantStore must not be null"); + Validate.notNull(delivery,"Delivery must not be null"); + Validate.notEmpty(products,"products must not be empty"); + Validate.notNull(language,"Language must not be null"); + + + + ShippingQuote shippingQuote = new ShippingQuote(); + ShippingQuoteModule shippingQuoteModule = null; + + try { + + + if(StringUtils.isBlank(delivery.getPostalCode())) { + shippingQuote.getWarnings().add("No postal code in delivery address"); + shippingQuote.setShippingReturnCode(ShippingQuote.NO_POSTAL_CODE); + } + + //get configuration + ShippingConfiguration shippingConfiguration = getShippingConfiguration(store); + ShippingType shippingType = ShippingType.INTERNATIONAL; + + /** get shipping origin **/ + ShippingOrigin shippingOrigin = shippingOriginService.getByStore(store); + if(shippingOrigin == null || !shippingOrigin.isActive()) { + shippingOrigin = new ShippingOrigin(); + shippingOrigin.setAddress(store.getStoreaddress()); + shippingOrigin.setCity(store.getStorecity()); + shippingOrigin.setCountry(store.getCountry()); + shippingOrigin.setPostalCode(store.getStorepostalcode()); + shippingOrigin.setState(store.getStorestateprovince()); + shippingOrigin.setZone(store.getZone()); + } + + + if(shippingConfiguration==null) { + shippingConfiguration = new ShippingConfiguration(); + } + + if(shippingConfiguration.getShippingType()!=null) { + shippingType = shippingConfiguration.getShippingType(); + } + + //look if customer country code excluded + Country shipCountry = delivery.getCountry(); + + //a ship to country is required + Validate.notNull(shipCountry,"Ship to Country cannot be null"); + Validate.notNull(store.getCountry(), "Store Country canot be null"); + + if(shippingType.name().equals(ShippingType.NATIONAL.name())){ + //customer country must match store country + if(!shipCountry.getIsoCode().equals(store.getCountry().getIsoCode())) { + shippingQuote.setShippingReturnCode(ShippingQuote.NO_SHIPPING_TO_SELECTED_COUNTRY + " " + shipCountry.getIsoCode()); + return shippingQuote; + } + } else if(shippingType.name().equals(ShippingType.INTERNATIONAL.name())){ + + //customer shipping country code must be in accepted list + List supportedCountries = this.getSupportedCountries(store); + if(!supportedCountries.contains(shipCountry.getIsoCode())) { + shippingQuote.setShippingReturnCode(ShippingQuote.NO_SHIPPING_TO_SELECTED_COUNTRY + " " + shipCountry.getIsoCode()); + return shippingQuote; + } + } + + //must have a shipping module configured + Map modules = this.getShippingModulesConfigured(store); + if(modules == null){ + shippingQuote.setShippingReturnCode(ShippingQuote.NO_SHIPPING_MODULE_CONFIGURED); + return shippingQuote; + } + + + /** uses this module name **/ + String moduleName = null; + IntegrationConfiguration configuration = null; + for(String module : modules.keySet()) { + moduleName = module; + configuration = modules.get(module); + //use the first active module + if(configuration.isActive()) { + shippingQuoteModule = shippingModules.get(module); + if(shippingQuoteModule instanceof ShippingQuotePrePostProcessModule) { + shippingQuoteModule = null; + continue; + } else { + break; + } + } + } + + if(shippingQuoteModule==null){ + shippingQuote.setShippingReturnCode(ShippingQuote.NO_SHIPPING_MODULE_CONFIGURED); + return shippingQuote; + } + + /** merchant module configs **/ + List shippingMethods = this.getShippingMethods(store); + IntegrationModule shippingModule = null; + for(IntegrationModule mod : shippingMethods) { + if(mod.getCode().equals(moduleName)){ + shippingModule = mod; + break; + } + } + + /** general module configs **/ + if(shippingModule==null) { + shippingQuote.setShippingReturnCode(ShippingQuote.NO_SHIPPING_MODULE_CONFIGURED); + return shippingQuote; + } + + //calculate order total + BigDecimal orderTotal = calculateOrderTotal(products,store); + List packages = getPackagesDetails(products, store); + + //free shipping ? + boolean freeShipping = false; + if(shippingConfiguration.isFreeShippingEnabled()) { + BigDecimal freeShippingAmount = shippingConfiguration.getOrderTotalFreeShipping(); + if(freeShippingAmount!=null) { + if(orderTotal.doubleValue()>freeShippingAmount.doubleValue()) { + if(shippingConfiguration.getFreeShippingType() == ShippingType.NATIONAL) { + if(store.getCountry().getIsoCode().equals(shipCountry.getIsoCode())) { + freeShipping = true; + shippingQuote.setFreeShipping(true); + shippingQuote.setFreeShippingAmount(freeShippingAmount); + return shippingQuote; + } + } else {//international all + freeShipping = true; + shippingQuote.setFreeShipping(true); + shippingQuote.setFreeShippingAmount(freeShippingAmount); + return shippingQuote; + } + + } + } + } + + + //handling fees + BigDecimal handlingFees = shippingConfiguration.getHandlingFees(); + if(handlingFees!=null) { + shippingQuote.setHandlingFees(handlingFees); + } + + //tax basis + shippingQuote.setApplyTaxOnShipping(shippingConfiguration.isTaxOnShipping()); + + + Locale locale = languageService.toLocale(language, store); + + //invoke pre processors + //the main pre-processor determines at runtime the shipping module + //also available distance calculation + if(!CollectionUtils.isEmpty(shippingModulePreProcessors)) { + for(ShippingQuotePrePostProcessModule preProcessor : shippingModulePreProcessors) { + //System.out.println("Using pre-processor " + preProcessor.getModuleCode()); + preProcessor.prePostProcessShippingQuotes(shippingQuote, packages, orderTotal, delivery, shippingOrigin, store, configuration, shippingModule, shippingConfiguration, shippingMethods, locale); + //TODO switch module if required + if(shippingQuote.getCurrentShippingModule()!=null && !shippingQuote.getCurrentShippingModule().getCode().equals(shippingModule.getCode())) { + shippingModule = shippingQuote.getCurrentShippingModule();//determines the shipping module + configuration = modules.get(shippingModule.getCode()); + if(configuration!=null) { + if(configuration.isActive()) { + moduleName = shippingModule.getCode(); + shippingQuoteModule = this.shippingModules.get(shippingModule.getCode()); + configuration = modules.get(shippingModule.getCode()); + } //TODO use default + } + + } + } + } + + //invoke module + List shippingOptions = null; + + try { + shippingOptions = shippingQuoteModule.getShippingQuotes(shippingQuote, packages, orderTotal, delivery, shippingOrigin, store, configuration, shippingModule, shippingConfiguration, locale); + } catch(Exception e) { + LOGGER.error("Error while calculating shipping : " + e.getMessage(), e); +/* merchantLogService.save( + new MerchantLog(store, + "Can't process " + shippingModule.getModule() + + " -> " + + e.getMessage())); + shippingQuote.setQuoteError(e.getMessage()); + shippingQuote.setShippingReturnCode(ShippingQuote.ERROR); + return shippingQuote;*/ + } + + if(shippingOptions==null && !StringUtils.isBlank(delivery.getPostalCode())) { + + //absolutely need to use in this case store pickup or other default shipping quote + shippingQuote.setShippingReturnCode(ShippingQuote.NO_SHIPPING_TO_SELECTED_COUNTRY); + } + + + shippingQuote.setShippingModuleCode(moduleName); + + //filter shipping options + ShippingOptionPriceType shippingOptionPriceType = shippingConfiguration.getShippingOptionPriceType(); + ShippingOption selectedOption = null; + + if(shippingOptions!=null) { + + for(ShippingOption option : shippingOptions) { + if(selectedOption==null) { + selectedOption = option; + } + //set price text + String priceText = pricingService.getDisplayAmount(option.getOptionPrice(), store); + option.setOptionPriceText(priceText); + option.setShippingModuleCode(moduleName); + + if(StringUtils.isBlank(option.getOptionName())) { + + String countryName = delivery.getCountry().getName(); + if(countryName == null) { + Map deliveryCountries = countryService.getCountriesMap(language); + Country dCountry = deliveryCountries.get(delivery.getCountry().getIsoCode()); + if(dCountry!=null) { + countryName = dCountry.getName(); + } else { + countryName = delivery.getCountry().getIsoCode(); + } + } + option.setOptionName(countryName); + } + + if(shippingOptionPriceType.name().equals(ShippingOptionPriceType.HIGHEST.name())) { + + if (option.getOptionPrice() + .longValue() > selectedOption + .getOptionPrice() + .longValue()) { + selectedOption = option; + } + } + + + if(shippingOptionPriceType.name().equals(ShippingOptionPriceType.LEAST.name())) { + + if (option.getOptionPrice() + .longValue() < selectedOption + .getOptionPrice() + .longValue()) { + selectedOption = option; + } + } + + + if(shippingOptionPriceType.name().equals(ShippingOptionPriceType.ALL.name())) { + + if (option.getOptionPrice() + .longValue() < selectedOption + .getOptionPrice() + .longValue()) { + selectedOption = option; + } + } + + } + + shippingQuote.setSelectedShippingOption(selectedOption); + + if(selectedOption!=null && !shippingOptionPriceType.name().equals(ShippingOptionPriceType.ALL.name())) { + shippingOptions = new ArrayList(); + shippingOptions.add(selectedOption); + } + + } + + /** set final delivery address **/ + shippingQuote.setDeliveryAddress(delivery); + + shippingQuote.setShippingOptions(shippingOptions); + + /** post processors **/ + //invoke pre processors + if(!CollectionUtils.isEmpty(shippingModulePostProcessors)) { + for(ShippingQuotePrePostProcessModule postProcessor : shippingModulePostProcessors) { + //get module info + + //get module configuration + IntegrationConfiguration integrationConfiguration = modules.get(postProcessor.getModuleCode()); + + IntegrationModule postProcessModule = null; + for(IntegrationModule mod : shippingMethods) { + if(mod.getCode().equals(postProcessor.getModuleCode())){ + postProcessModule = mod; + break; + } + } + + IntegrationModule module = postProcessModule; + if(integrationConfiguration != null) { + postProcessor.prePostProcessShippingQuotes(shippingQuote, packages, orderTotal, delivery, shippingOrigin, store, integrationConfiguration, module, shippingConfiguration, shippingMethods, locale); + } + } + } + String ipAddress = null; + UserContext context = UserContext.getCurrentInstance(); + if(context != null) { + ipAddress = context.getIpAddress(); + } + + if(shippingQuote!=null && CollectionUtils.isNotEmpty(shippingQuote.getShippingOptions())) { + //save SHIPPING OPTIONS + List finalShippingOptions = shippingQuote.getShippingOptions(); + for(ShippingOption option : finalShippingOptions) { + + //transform to Quote + Quote q = new Quote(); + q.setCartId(shoppingCartId); + q.setDelivery(delivery); + if(!StringUtils.isBlank(ipAddress)) { + q.setIpAddress(ipAddress); + } + if(!StringUtils.isBlank(option.getEstimatedNumberOfDays())) { + try { + q.setEstimatedNumberOfDays(Integer.valueOf(option.getEstimatedNumberOfDays())); + } catch(Exception e) { + LOGGER.error("Cannot cast to integer " + option.getEstimatedNumberOfDays()); + } + } + + if(freeShipping) { + q.setFreeShipping(true); + q.setPrice(new BigDecimal(0)); + q.setModule("FREE"); + q.setOptionCode("FREE"); + q.setOptionName("FREE"); + } else { + q.setModule(option.getShippingModuleCode()); + q.setOptionCode(option.getOptionCode()); + if(!StringUtils.isBlank(option.getOptionDeliveryDate())) { + try { + //q.setOptionDeliveryDate(DateUtil.formatDate(option.getOptionDeliveryDate())); + } catch(Exception e) { + LOGGER.error("Cannot transform to date " + option.getOptionDeliveryDate()); + } + } + q.setOptionName(option.getOptionName()); + q.setOptionShippingDate(new Date()); + q.setPrice(option.getOptionPrice()); + + } + + if(handlingFees != null) { + q.setHandling(handlingFees); + } + + q.setQuoteDate(new Date()); + shippingQuoteService.save(q); + option.setShippingQuoteOptionId(q.getId()); + + } + } + + + + } catch (Exception e) { + LOGGER.error(e.getMessage(), e); + throw new ServiceException(e); + } + + return shippingQuote; + + } + + @Override + public List getSupportedCountries(MerchantStore store) throws ServiceException { + + List supportedCountries = new ArrayList(); + MerchantConfiguration configuration = merchantConfigurationService.getMerchantConfiguration(SUPPORTED_COUNTRIES, store); + + if(configuration!=null) { + + String countries = configuration.getValue(); + if(!StringUtils.isBlank(countries)) { + + Object objRegions=JSONValue.parse(countries); + JSONArray arrayRegions=(JSONArray)objRegions; + for (Object arrayRegion : arrayRegions) { + supportedCountries.add((String) arrayRegion); + } + } + + } + + return supportedCountries; + } + + @Override + public List getShipToCountryList(MerchantStore store, Language language) throws ServiceException { + + + ShippingConfiguration shippingConfiguration = getShippingConfiguration(store); + ShippingType shippingType = ShippingType.INTERNATIONAL; + List supportedCountries = new ArrayList(); + if(shippingConfiguration==null) { + shippingConfiguration = new ShippingConfiguration(); + } + + if(shippingConfiguration.getShippingType()!=null) { + shippingType = shippingConfiguration.getShippingType(); + } + + + if(shippingType.name().equals(ShippingType.NATIONAL.name())){ + + supportedCountries.add(store.getCountry().getIsoCode()); + + } else { + + MerchantConfiguration configuration = merchantConfigurationService.getMerchantConfiguration(SUPPORTED_COUNTRIES, store); + + if(configuration!=null) { + + String countries = configuration.getValue(); + if(!StringUtils.isBlank(countries)) { + + Object objRegions=JSONValue.parse(countries); + JSONArray arrayRegions=(JSONArray)objRegions; + for (Object arrayRegion : arrayRegions) { + supportedCountries.add((String) arrayRegion); + } + } + + } + + } + + return countryService.getCountries(supportedCountries, language); + + } + + + @Override + public void setSupportedCountries(MerchantStore store, List countryCodes) throws ServiceException { + + + //transform a list of string to json entry + ObjectMapper mapper = new ObjectMapper(); + + try { + String value = mapper.writeValueAsString(countryCodes); + + MerchantConfiguration configuration = merchantConfigurationService.getMerchantConfiguration(SUPPORTED_COUNTRIES, store); + + if(configuration==null) { + configuration = new MerchantConfiguration(); + configuration. + setKey(SUPPORTED_COUNTRIES); + configuration.setMerchantStore(store); + } + + configuration.setValue(value); + + merchantConfigurationService.saveOrUpdate(configuration); + + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + + private BigDecimal calculateOrderTotal(List products, MerchantStore store) throws Exception { + + BigDecimal total = new BigDecimal(0); + for(ShippingProduct shippingProduct : products) { + BigDecimal currentPrice = shippingProduct.getFinalPrice().getFinalPrice(); + currentPrice = currentPrice.multiply(new BigDecimal(shippingProduct.getQuantity())); + total = total.add(currentPrice); + } + + + return total; + + + } + + @Override + public List getPackagesDetails( + List products, MerchantStore store) + throws ServiceException { + + List packages = null; + + ShippingConfiguration shippingConfiguration = this.getShippingConfiguration(store); + //determine if the system has to use BOX or ITEM + ShippingPackageType shippingPackageType = ShippingPackageType.ITEM; + if(shippingConfiguration!=null) { + shippingPackageType = shippingConfiguration.getShippingPackageType(); + } + + if(shippingPackageType.name().equals(ShippingPackageType.BOX.name())){ + packages = packaging.getBoxPackagesDetails(products, store); + } else { + packages = packaging.getItemPackagesDetails(products, store); + } + + return packages; + + } + + @Override + public boolean requiresShipping(List items, + MerchantStore store) throws ServiceException { + + boolean requiresShipping = false; + for(ShoppingCartItem item : items) { + Product product = item.getProduct(); + if(!product.isProductVirtual() && product.isProductShipeable()) { + requiresShipping = true; + } + } + + return requiresShipping; + } + + @Override + public ShippingMetaData getShippingMetaData(MerchantStore store) + throws ServiceException { + + + try { + + ShippingMetaData metaData = new ShippingMetaData(); + + // configured country + List countries = getShipToCountryList(store, store.getDefaultLanguage()); + metaData.setShipToCountry(countries); + + // configured modules + Map modules = Optional.ofNullable(getShippingModulesConfigured(store)) + .orElse(Collections.emptyMap()); + metaData.setModules(new ArrayList<>(modules.keySet())); + + // pre processors + List preProcessors = this.shippingModulePreProcessors; + List preProcessorKeys = new ArrayList(); + if(preProcessors!=null) { + for(ShippingQuotePrePostProcessModule processor : preProcessors) { + preProcessorKeys.add(processor.getModuleCode()); + if(SHIPPING_DISTANCE.equals(processor.getModuleCode())) { + metaData.setUseDistanceModule(true); + } + } + } + metaData.setPreProcessors(preProcessorKeys); + + //post processors + List postProcessors = this.shippingModulePostProcessors; + List postProcessorKeys = new ArrayList(); + if(postProcessors!=null) { + for(ShippingQuotePrePostProcessModule processor : postProcessors) { + postProcessorKeys.add(processor.getModuleCode()); + } + } + metaData.setPostProcessors(postProcessorKeys); + + + return metaData; + + } catch(Exception e) { + throw new ServiceException("Exception while getting shipping metadata ",e); + } + } + + @Override + public boolean hasTaxOnShipping(MerchantStore store) throws ServiceException { + ShippingConfiguration shippingConfiguration = getShippingConfiguration(store); + return shippingConfiguration.isTaxOnShipping(); + } +} \ No newline at end of file diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/shoppingcart/ShoppingCartCalculationService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/shoppingcart/ShoppingCartCalculationService.java new file mode 100755 index 0000000000..198c23d422 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/shoppingcart/ShoppingCartCalculationService.java @@ -0,0 +1,48 @@ +/** + * + */ +package com.salesmanager.core.business.services.shoppingcart; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.OrderTotalSummary; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; + +/** + * Interface declaring various methods used to calculate {@link ShoppingCart} + * object details. + * + * @author Umesh Awasthi + * @since 1.2 + * + */ +public interface ShoppingCartCalculationService { + /** + * Method which will be used to calculate price for each line items as well + * Total and Sub-total for {@link ShoppingCart}. + * + * @param cartModel + * ShoopingCart mode representing underlying DB object + * @param customer + * @param store + * @param language + * @throws ServiceException + */ + OrderTotalSummary calculate(final ShoppingCart cartModel, final Customer customer, final MerchantStore store, + final Language language) throws ServiceException; + + /** + * Method which will be used to calculate price for each line items as well + * Total and Sub-total for {@link ShoppingCart}. + * + * @param cartModel + * ShoopingCart mode representing underlying DB object + * @param store + * @param language + * @throws ServiceException + */ + OrderTotalSummary calculate(final ShoppingCart cartModel, final MerchantStore store, final Language language) + throws ServiceException; +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/shoppingcart/ShoppingCartCalculationServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/shoppingcart/ShoppingCartCalculationServiceImpl.java new file mode 100755 index 0000000000..9f5df77019 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/shoppingcart/ShoppingCartCalculationServiceImpl.java @@ -0,0 +1,121 @@ +/** + * + */ +package com.salesmanager.core.business.services.shoppingcart; + +import javax.inject.Inject; + +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.order.OrderService; +import com.salesmanager.core.business.services.order.OrderServiceImpl; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.OrderTotalSummary; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; + +/** + *

    + * Implementation class responsible for calculating state of shopping cart. This + * class will take care of calculating price of each line items of shopping cart + * as well any discount including sub-total and total amount. + *

    + * + * @author Umesh Awasthi + * @version 1.2 + */ +@Service("shoppingCartCalculationService") +public class ShoppingCartCalculationServiceImpl implements ShoppingCartCalculationService { + + protected final Logger LOG = LoggerFactory.getLogger(getClass()); + + @Inject + private ShoppingCartService shoppingCartService; + + @Inject + private OrderService orderService; + + /** + *

    + * Method used to recalculate state of shopping cart every time any change + * has been made to underlying {@link ShoppingCart} object in DB. + *

    + * Following operations will be performed by this method. + * + *
  • Calculate price for each {@link ShoppingCartItem} and update it.
  • + *

    + * This method is backbone method for all price calculation related to + * shopping cart. + *

    + * + * @see OrderServiceImpl + * + * @param cartModel + * @param customer + * @param store + * @param language + * @throws ServiceException + */ + @Override + public OrderTotalSummary calculate(final ShoppingCart cartModel, final Customer customer, final MerchantStore store, + final Language language) throws ServiceException { + + Validate.notNull(cartModel, "cart cannot be null"); + Validate.notNull(cartModel.getLineItems(), "Cart should have line items."); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(customer, "Customer cannot be null"); + OrderTotalSummary orderTotalSummary = orderService.calculateShoppingCartTotal(cartModel, customer, store, + language); + updateCartModel(cartModel); + return orderTotalSummary; + + } + + /** + *

    + * Method used to recalculate state of shopping cart every time any change + * has been made to underlying {@link ShoppingCart} object in DB. + *

    + * Following operations will be performed by this method. + * + *
  • Calculate price for each {@link ShoppingCartItem} and update it.
  • + *

    + * This method is backbone method for all price calculation related to + * shopping cart. + *

    + * + * @see OrderServiceImpl + * + * @param cartModel + * @param store + * @param language + * @throws ServiceException + */ + @Override + public OrderTotalSummary calculate(final ShoppingCart cartModel, final MerchantStore store, final Language language) + throws ServiceException { + + Validate.notNull(cartModel, "cart cannot be null"); + Validate.notNull(cartModel.getLineItems(), "Cart should have line items."); + Validate.notNull(store, "MerchantStore cannot be null"); + OrderTotalSummary orderTotalSummary = orderService.calculateShoppingCartTotal(cartModel, store, language); + updateCartModel(cartModel); + return orderTotalSummary; + + } + + public ShoppingCartService getShoppingCartService() { + return shoppingCartService; + } + + private void updateCartModel(final ShoppingCart cartModel) throws ServiceException { + shoppingCartService.saveOrUpdate(cartModel); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/shoppingcart/ShoppingCartService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/shoppingcart/ShoppingCartService.java new file mode 100755 index 0000000000..6fad8bf281 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/shoppingcart/ShoppingCartService.java @@ -0,0 +1,67 @@ +package com.salesmanager.core.business.services.shoppingcart; + +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.shipping.ShippingProduct; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; + +public interface ShoppingCartService extends SalesManagerEntityService { + + ShoppingCart getShoppingCart(Customer customer, MerchantStore store) throws ServiceException; + + void saveOrUpdate(ShoppingCart shoppingCart) throws ServiceException; + + ShoppingCart getById(Long id, MerchantStore store) throws ServiceException; + + ShoppingCart getByCode(String code, MerchantStore store) throws ServiceException; + + + /** + * Creates a list of ShippingProduct based on the ShoppingCart if items are + * virtual return list will be null + * + * @param cart + * @return + * @throws ServiceException + */ + List createShippingProduct(ShoppingCart cart) throws ServiceException; + + /** + * Populates a ShoppingCartItem from a Product and attributes if any. Calculate price based on availability + * + * @param product + * @return + * @throws ServiceException + */ + ShoppingCartItem populateShoppingCartItem(Product product, MerchantStore store) throws ServiceException; + + void deleteCart(ShoppingCart cart) throws ServiceException; + + void removeShoppingCart(ShoppingCart cart) throws ServiceException; + + /** + * + * @param userShoppingModel + * @param sessionCart + * @param store + * @return {@link ShoppingCart} merged Shopping Cart + * @throws Exception + */ + ShoppingCart mergeShoppingCarts(final ShoppingCart userShoppingCart, final ShoppingCart sessionCart, + final MerchantStore store) throws Exception; + + + /** + * Removes a shopping cart item + * @param item + */ + void deleteShoppingCartItem(Long id); + +} \ No newline at end of file diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/shoppingcart/ShoppingCartServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/shoppingcart/ShoppingCartServiceImpl.java new file mode 100755 index 0000000000..e0d1ce8d1b --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/shoppingcart/ShoppingCartServiceImpl.java @@ -0,0 +1,513 @@ +package com.salesmanager.core.business.services.shoppingcart; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.shoppingcart.ShoppingCartAttributeRepository; +import com.salesmanager.core.business.repositories.shoppingcart.ShoppingCartItemRepository; +import com.salesmanager.core.business.repositories.shoppingcart.ShoppingCartRepository; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.common.UserContext; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.shipping.ShippingProduct; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.core.model.shoppingcart.ShoppingCartAttributeItem; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.inject.Inject; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +@Service("shoppingCartService") +public class ShoppingCartServiceImpl extends SalesManagerEntityServiceImpl + implements ShoppingCartService { + + private ShoppingCartRepository shoppingCartRepository; + + @Inject + private ProductService productService; + + @Inject + private ShoppingCartItemRepository shoppingCartItemRepository; + + @Inject + private ShoppingCartAttributeRepository shoppingCartAttributeItemRepository; + + @Inject + private PricingService pricingService; + + @Inject + private ProductAttributeService productAttributeService; + + private static final Logger LOGGER = LoggerFactory.getLogger(ShoppingCartServiceImpl.class); + + @Inject + public ShoppingCartServiceImpl(ShoppingCartRepository shoppingCartRepository) { + super(shoppingCartRepository); + this.shoppingCartRepository = shoppingCartRepository; + + } + + /** + * Retrieve a {@link ShoppingCart} cart for a given customer + */ + @Override + @Transactional + public ShoppingCart getShoppingCart(final Customer customer, MerchantStore store) throws ServiceException { + + try { + + List shoppingCarts = shoppingCartRepository.findByCustomer(customer.getId()); + + // elect valid shopping cart + List validCart = shoppingCarts.stream().filter((cart) -> cart.getOrderId() == null) + .collect(Collectors.toList()); + + ShoppingCart shoppingCart = null; + + if (!CollectionUtils.isEmpty(validCart)) { + shoppingCart = validCart.get(0); + getPopulatedShoppingCart(shoppingCart, store); + if (shoppingCart != null && shoppingCart.isObsolete()) { + delete(shoppingCart); + shoppingCart = null; + } + } + + return shoppingCart; + + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + /** + * Save or update a {@link ShoppingCart} for a given customer + */ + @Override + public void saveOrUpdate(ShoppingCart shoppingCart) throws ServiceException { + + Validate.notNull(shoppingCart, "ShoppingCart must not be null"); + Validate.notNull(shoppingCart.getMerchantStore(), "ShoppingCart.merchantStore must not be null"); + + try { + UserContext userContext = UserContext.getCurrentInstance(); + if (userContext != null) { + shoppingCart.setIpAddress(userContext.getIpAddress()); + } + } catch (Exception s) { + LOGGER.error("Cannot add ip address to shopping cart ", s); + } + + if (shoppingCart.getId() == null || shoppingCart.getId() == 0) { + super.create(shoppingCart); + } else { + super.update(shoppingCart); + } + + } + + /** + * Get a {@link ShoppingCart} for a given id and MerchantStore. Will update the + * shopping cart prices and items based on the actual inventory. This method + * will remove the shopping cart if no items are attached. + */ + @Override + @Transactional + public ShoppingCart getById(final Long id, final MerchantStore store) throws ServiceException { + + try { + ShoppingCart shoppingCart = shoppingCartRepository.findById(store.getId(), id); + if (shoppingCart == null) { + return null; + } + getPopulatedShoppingCart(shoppingCart, store); + + if (shoppingCart.isObsolete()) { + delete(shoppingCart); + return null; + } else { + return shoppingCart; + } + + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + /** + * Get a {@link ShoppingCart} for a given id. Will update the shopping cart + * prices and items based on the actual inventory. This method will remove the + * shopping cart if no items are attached. + */ + /* + * @Override + * + * @Transactional public ShoppingCart getById(final Long id, MerchantStore + * store) throws { + * + * try { ShoppingCart shoppingCart = shoppingCartRepository.findOne(id); if + * (shoppingCart == null) { return null; } + * getPopulatedShoppingCart(shoppingCart); + * + * if (shoppingCart.isObsolete()) { delete(shoppingCart); return null; } else { + * return shoppingCart; } } catch (Exception e) { // TODO Auto-generated catch + * block e.printStackTrace(); } return null; + * + * } + */ + + /** + * Get a {@link ShoppingCart} for a given code. Will update the shopping cart + * prices and items based on the actual inventory. This method will remove the + * shopping cart if no items are attached. + */ + @Override + @Transactional + public ShoppingCart getByCode(final String code, final MerchantStore store) throws ServiceException { + + try { + ShoppingCart shoppingCart = shoppingCartRepository.findByCode(store.getId(), code); + if (shoppingCart == null) { + return null; + } + getPopulatedShoppingCart(shoppingCart, store); + + if (shoppingCart.isObsolete()) { + delete(shoppingCart); + return null; + } else { + return shoppingCart; + } + + } catch (javax.persistence.NoResultException nre) { + return null; + } catch (Throwable e) { + throw new ServiceException(e); + } + + } + + @Override + @Transactional + public void deleteCart(final ShoppingCart shoppingCart) throws ServiceException { + ShoppingCart cart = this.getById(shoppingCart.getId()); + if (cart != null) { + super.delete(cart); + } + } + + /* + * @Override + * + * @Transactional public ShoppingCart getByCustomer(final Customer customer) + * throws ServiceException { + * + * try { List shoppingCart = + * shoppingCartRepository.findByCustomer(customer.getId()); if (shoppingCart == + * null) { return null; } return getPopulatedShoppingCart(shoppingCart); + * + * } catch (Exception e) { throw new ServiceException(e); } } + */ + + @Transactional(noRollbackFor = { org.springframework.dao.EmptyResultDataAccessException.class }) + private ShoppingCart getPopulatedShoppingCart(final ShoppingCart shoppingCart, MerchantStore store) throws Exception { + + try { + + boolean cartIsObsolete = false; + if (shoppingCart != null) { + + Set items = shoppingCart.getLineItems(); + if (items == null || items.size() == 0) { + shoppingCart.setObsolete(true); + return shoppingCart; + + } + + // Set shoppingCartItems = new + // HashSet(); + for (ShoppingCartItem item : items) { + LOGGER.debug("Populate item " + item.getId()); + getPopulatedItem(item, store); + LOGGER.debug("Obsolete item ? " + item.isObsolete()); + if (item.isObsolete()) { + cartIsObsolete = true; + } + } + + Set refreshedItems = new HashSet<>(items); + + shoppingCart.setLineItems(refreshedItems); + update(shoppingCart); + + if (cartIsObsolete) { + shoppingCart.setObsolete(true); + } + return shoppingCart; + } + + } catch (Exception e) { + LOGGER.error(e.getMessage()); + throw new ServiceException(e); + } + + return shoppingCart; + + } + + @Override + public ShoppingCartItem populateShoppingCartItem(Product product, MerchantStore store) throws ServiceException { + Validate.notNull(product, "Product should not be null"); + Validate.notNull(product.getMerchantStore(), "Product.merchantStore should not be null"); + Validate.notNull(store, "MerchantStore should not be null"); + + ShoppingCartItem item = new ShoppingCartItem(product); + item.setSku(product.getSku());//already in the constructor + + // set item price + FinalPrice price = pricingService.calculateProductPrice(product); + item.setItemPrice(price.getFinalPrice()); + return item; + + } + + @Transactional + private void getPopulatedItem(final ShoppingCartItem item, MerchantStore store) throws Exception { + + Product product = productService.getBySku(item.getSku(), store, store.getDefaultLanguage()); + + if (product == null) { + item.setObsolete(true); + return; + } + + item.setProduct(product); + item.setSku(product.getSku()); + + if (product.isProductVirtual()) { + item.setProductVirtual(true); + } + + Set cartAttributes = item.getAttributes(); + Set productAttributes = product.getAttributes(); + List attributesList = new ArrayList();// attributes maintained + List removeAttributesList = new ArrayList();// attributes + // to remove + // DELETE ORPHEANS MANUALLY + if ((productAttributes != null && productAttributes.size() > 0) + || (cartAttributes != null && cartAttributes.size() > 0)) { + if (cartAttributes != null) { + for (ShoppingCartAttributeItem attribute : cartAttributes) { + long attributeId = attribute.getProductAttributeId(); + boolean existingAttribute = false; + for (ProductAttribute productAttribute : productAttributes) { + + if (productAttribute.getId().equals(attributeId)) { + attribute.setProductAttribute(productAttribute); + attributesList.add(productAttribute); + existingAttribute = true; + break; + } + } + + if (!existingAttribute) { + removeAttributesList.add(attribute); + } + + } + } + } + + // cleanup orphean item + if (CollectionUtils.isNotEmpty(removeAttributesList)) { + for (ShoppingCartAttributeItem attr : removeAttributesList) { + shoppingCartAttributeItemRepository.delete(attr); + } + } + + // cleanup detached attributes + if (CollectionUtils.isEmpty(attributesList)) { + item.setAttributes(null); + } + + // set item price + FinalPrice price = pricingService.calculateProductPrice(product, attributesList); + item.setItemPrice(price.getFinalPrice()); + item.setFinalPrice(price); + + BigDecimal subTotal = item.getItemPrice().multiply(new BigDecimal(item.getQuantity())); + item.setSubTotal(subTotal); + + } + + @Override + public List createShippingProduct(final ShoppingCart cart) throws ServiceException { + /** + * Determines if products are virtual + */ + Set items = cart.getLineItems(); + List shippingProducts = null; + for (ShoppingCartItem item : items) { + Product product = item.getProduct(); + if (!product.isProductVirtual() && product.isProductShipeable()) { + if (shippingProducts == null) { + shippingProducts = new ArrayList(); + } + ShippingProduct shippingProduct = new ShippingProduct(product); + shippingProduct.setQuantity(item.getQuantity()); + shippingProduct.setFinalPrice(item.getFinalPrice()); + shippingProducts.add(shippingProduct); + } + } + + return shippingProducts; + + } + + @Override + public void removeShoppingCart(final ShoppingCart cart) throws ServiceException { + shoppingCartRepository.delete(cart); + } + + @Override + public ShoppingCart mergeShoppingCarts(final ShoppingCart userShoppingModel, final ShoppingCart sessionCart, + final MerchantStore store) throws Exception { + if (sessionCart.getCustomerId() != null + && sessionCart.getCustomerId().equals(userShoppingModel.getCustomerId())) { + LOGGER.info("Session Shopping cart belongs to same logged in user"); + if (CollectionUtils.isNotEmpty(userShoppingModel.getLineItems()) + && CollectionUtils.isNotEmpty(sessionCart.getLineItems())) { + return userShoppingModel; + } + } + + LOGGER.info("Starting merging shopping carts"); + if (CollectionUtils.isNotEmpty(sessionCart.getLineItems())) { + Set shoppingCartItemsSet = getShoppingCartItems(sessionCart, store, userShoppingModel); + boolean duplicateFound = false; + if (CollectionUtils.isNotEmpty(shoppingCartItemsSet)) { + for (ShoppingCartItem sessionShoppingCartItem : shoppingCartItemsSet) { + if (CollectionUtils.isNotEmpty(userShoppingModel.getLineItems())) { + for (ShoppingCartItem cartItem : userShoppingModel.getLineItems()) { + if (cartItem.getProduct().getId().longValue() == sessionShoppingCartItem.getProduct() + .getId().longValue()) { + if (CollectionUtils.isNotEmpty(cartItem.getAttributes())) { + if (!duplicateFound) { + LOGGER.info("Dupliate item found..updating exisitng product quantity"); + cartItem.setQuantity( + cartItem.getQuantity() + sessionShoppingCartItem.getQuantity()); + duplicateFound = true; + break; + } + } + } + } + } + if (!duplicateFound) { + LOGGER.info("New item found..adding item to Shopping cart"); + userShoppingModel.getLineItems().add(sessionShoppingCartItem); + } + } + + } + + } + LOGGER.info("Shopping Cart merged successfully....."); + saveOrUpdate(userShoppingModel); + removeShoppingCart(sessionCart); + + return userShoppingModel; + } + + private Set getShoppingCartItems(final ShoppingCart sessionCart, final MerchantStore store, + final ShoppingCart cartModel) throws Exception { + + Set shoppingCartItemsSet = null; + if (CollectionUtils.isNotEmpty(sessionCart.getLineItems())) { + shoppingCartItemsSet = new HashSet(); + for (ShoppingCartItem shoppingCartItem : sessionCart.getLineItems()) { + Product product = productService.getBySku(shoppingCartItem.getSku(), store, store.getDefaultLanguage()); + //.getById(shoppingCartItem.getProductId()); + if (product == null) { + throw new Exception("Item with sku " + shoppingCartItem.getSku() + " does not exist"); + } + + if (product.getMerchantStore().getId().intValue() != store.getId().intValue()) { + throw new Exception("Item with sku " + shoppingCartItem.getSku() + + " does not belong to merchant " + store.getId()); + } + + ShoppingCartItem item = populateShoppingCartItem(product, store); + item.setQuantity(shoppingCartItem.getQuantity()); + item.setShoppingCart(cartModel); + + List cartAttributes = new ArrayList(); + if (shoppingCartItem != null && !CollectionUtils.isEmpty(shoppingCartItem.getAttributes())) { + cartAttributes.addAll(shoppingCartItem.getAttributes()); + if (CollectionUtils.isNotEmpty(cartAttributes)) { + for (ShoppingCartAttributeItem shoppingCartAttributeItem : cartAttributes) { + ProductAttribute productAttribute = productAttributeService + .getById(shoppingCartAttributeItem.getId()); + if (productAttribute != null && productAttribute.getProduct().getId().longValue() == product + .getId().longValue()) { + + ShoppingCartAttributeItem attributeItem = new ShoppingCartAttributeItem(item, + productAttribute); + if (shoppingCartAttributeItem.getId() > 0) { + attributeItem.setId(shoppingCartAttributeItem.getId()); + } + item.addAttributes(attributeItem); + + } + } + } + } + + shoppingCartItemsSet.add(item); + } + + } + return shoppingCartItemsSet; + } + + @Override + @Transactional + public void deleteShoppingCartItem(Long id) { + + ShoppingCartItem item = shoppingCartItemRepository.findOne(id); + if (item != null) { + + if (item.getAttributes() != null) { + item.getAttributes().forEach(a -> shoppingCartAttributeItemRepository.deleteById(a.getId())); + item.getAttributes().clear(); + } + + // refresh + item = shoppingCartItemRepository.findOne(id); + + // delete + shoppingCartItemRepository.deleteById(id); + + } + + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/system/EmailService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/system/EmailService.java new file mode 100755 index 0000000000..28046898c8 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/system/EmailService.java @@ -0,0 +1,19 @@ +package com.salesmanager.core.business.services.system; + + + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.email.Email; +import com.salesmanager.core.business.modules.email.EmailConfig; +import com.salesmanager.core.model.merchant.MerchantStore; + + +public interface EmailService { + + void sendHtmlEmail(MerchantStore store, Email email) throws ServiceException, Exception; + + EmailConfig getEmailConfiguration(MerchantStore store) throws ServiceException; + + void saveEmailConfiguration(EmailConfig emailConfig, MerchantStore store) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/system/EmailServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/system/EmailServiceImpl.java new file mode 100755 index 0000000000..ea43c48597 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/system/EmailServiceImpl.java @@ -0,0 +1,67 @@ +package com.salesmanager.core.business.services.system; + +import javax.inject.Inject; + +import org.springframework.stereotype.Service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.email.Email; +import com.salesmanager.core.business.modules.email.EmailConfig; +import com.salesmanager.core.business.modules.email.HtmlEmailSender; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.system.MerchantConfiguration; + +@Service("emailService") +public class EmailServiceImpl implements EmailService { + + @Inject + private MerchantConfigurationService merchantConfigurationService; + + @Inject + private HtmlEmailSender sender; + + @Override + public void sendHtmlEmail(MerchantStore store, Email email) throws ServiceException, Exception { + + EmailConfig emailConfig = getEmailConfiguration(store); + + sender.setEmailConfig(emailConfig); + sender.send(email); + } + + @Override + public EmailConfig getEmailConfiguration(MerchantStore store) throws ServiceException { + + MerchantConfiguration configuration = merchantConfigurationService.getMerchantConfiguration(Constants.EMAIL_CONFIG, store); + EmailConfig emailConfig = null; + if(configuration!=null) { + String value = configuration.getValue(); + + ObjectMapper mapper = new ObjectMapper(); + try { + emailConfig = mapper.readValue(value, EmailConfig.class); + } catch(Exception e) { + throw new ServiceException("Cannot parse json string " + value); + } + } + return emailConfig; + } + + + @Override + public void saveEmailConfiguration(EmailConfig emailConfig, MerchantStore store) throws ServiceException { + MerchantConfiguration configuration = merchantConfigurationService.getMerchantConfiguration(Constants.EMAIL_CONFIG, store); + if(configuration==null) { + configuration = new MerchantConfiguration(); + configuration.setMerchantStore(store); + configuration.setKey(Constants.EMAIL_CONFIG); + } + + String value = emailConfig.toJSONString(); + configuration.setValue(value); + merchantConfigurationService.saveOrUpdate(configuration); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/system/MerchantConfigurationService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/system/MerchantConfigurationService.java new file mode 100755 index 0000000000..0c80f9fa4b --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/system/MerchantConfigurationService.java @@ -0,0 +1,31 @@ +package com.salesmanager.core.business.services.system; + +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.system.MerchantConfig; +import com.salesmanager.core.model.system.MerchantConfiguration; +import com.salesmanager.core.model.system.MerchantConfigurationType; + +public interface MerchantConfigurationService extends + SalesManagerEntityService { + + MerchantConfiguration getMerchantConfiguration(String key, MerchantStore store) throws ServiceException; + + void saveOrUpdate(MerchantConfiguration entity) throws ServiceException; + + List listByStore(MerchantStore store) + throws ServiceException; + + List listByType(MerchantConfigurationType type, + MerchantStore store) throws ServiceException; + + MerchantConfig getMerchantConfig(MerchantStore store) + throws ServiceException; + + void saveMerchantConfig(MerchantConfig config, MerchantStore store) + throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/system/MerchantConfigurationServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/system/MerchantConfigurationServiceImpl.java new file mode 100755 index 0000000000..10452bf344 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/system/MerchantConfigurationServiceImpl.java @@ -0,0 +1,112 @@ +package com.salesmanager.core.business.services.system; + +import java.util.List; +import javax.inject.Inject; +import org.springframework.stereotype.Service; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.system.MerchantConfigurationRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.system.MerchantConfig; +import com.salesmanager.core.model.system.MerchantConfiguration; +import com.salesmanager.core.model.system.MerchantConfigurationType; + +@Service("merchantConfigurationService") +public class MerchantConfigurationServiceImpl extends + SalesManagerEntityServiceImpl implements + MerchantConfigurationService { + + private MerchantConfigurationRepository merchantConfigurationRepository; + + @Inject + public MerchantConfigurationServiceImpl( + MerchantConfigurationRepository merchantConfigurationRepository) { + super(merchantConfigurationRepository); + this.merchantConfigurationRepository = merchantConfigurationRepository; + } + + + @Override + public MerchantConfiguration getMerchantConfiguration(String key, MerchantStore store) throws ServiceException { + return merchantConfigurationRepository.findByMerchantStoreAndKey(store.getId(), key); + } + + @Override + public List listByStore(MerchantStore store) throws ServiceException { + return merchantConfigurationRepository.findByMerchantStore(store.getId()); + } + + @Override + public List listByType(MerchantConfigurationType type, MerchantStore store) throws ServiceException { + return merchantConfigurationRepository.findByMerchantStoreAndType(store.getId(), type); + } + + @Override + public void saveOrUpdate(MerchantConfiguration entity) throws ServiceException { + + + + if(entity.getId()!=null && entity.getId()>0) { + super.update(entity); + } else { + super.create(entity); + + } + } + + + @Override + public void delete(MerchantConfiguration merchantConfiguration) throws ServiceException { + MerchantConfiguration config = merchantConfigurationRepository.getOne(merchantConfiguration.getId()); + if(config!=null) { + super.delete(config); + } + } + + @Override + public MerchantConfig getMerchantConfig(MerchantStore store) throws ServiceException { + + MerchantConfiguration configuration = merchantConfigurationRepository.findByMerchantStoreAndKey(store.getId(), MerchantConfigurationType.CONFIG.name()); + + MerchantConfig config = null; + if(configuration!=null) { + String value = configuration.getValue(); + + ObjectMapper mapper = new ObjectMapper(); + try { + config = mapper.readValue(value, MerchantConfig.class); + } catch(Exception e) { + throw new ServiceException("Cannot parse json string " + value); + } + } + return config; + + } + + @Override + public void saveMerchantConfig(MerchantConfig config, MerchantStore store) throws ServiceException { + + MerchantConfiguration configuration = merchantConfigurationRepository.findByMerchantStoreAndKey(store.getId(), MerchantConfigurationType.CONFIG.name()); + + if(configuration==null) { + configuration = new MerchantConfiguration(); + configuration.setMerchantStore(store); + configuration.setKey(MerchantConfigurationType.CONFIG.name()); + configuration.setMerchantConfigurationType(MerchantConfigurationType.CONFIG); + } + + String value = config.toJSONString(); + configuration.setValue(value); + if(configuration.getId()!=null && configuration.getId()>0) { + super.update(configuration); + } else { + super.create(configuration); + + } + + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/system/MerchantLogService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/system/MerchantLogService.java new file mode 100755 index 0000000000..8fb67e0cd6 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/system/MerchantLogService.java @@ -0,0 +1,9 @@ +package com.salesmanager.core.business.services.system; + +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.system.MerchantLog; + +public interface MerchantLogService extends + SalesManagerEntityService { + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/system/MerchantLogServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/system/MerchantLogServiceImpl.java new file mode 100755 index 0000000000..e4c6f5d026 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/system/MerchantLogServiceImpl.java @@ -0,0 +1,38 @@ +package com.salesmanager.core.business.services.system; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.repositories.system.MerchantLogRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.system.MerchantLog; + +@Service("merchantLogService") +public class MerchantLogServiceImpl extends + SalesManagerEntityServiceImpl implements + MerchantLogService { + + @SuppressWarnings("unused") + private static final Logger LOGGER = LoggerFactory.getLogger(MerchantLogServiceImpl.class); + + + + private MerchantLogRepository merchantLogRepository; + + @Inject + public MerchantLogServiceImpl( + MerchantLogRepository merchantLogRepository) { + super(merchantLogRepository); + this.merchantLogRepository = merchantLogRepository; + } + + + + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/system/ModuleConfigurationService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/system/ModuleConfigurationService.java new file mode 100755 index 0000000000..014ed4ffb2 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/system/ModuleConfigurationService.java @@ -0,0 +1,25 @@ +package com.salesmanager.core.business.services.system; + +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.system.IntegrationModule; + +public interface ModuleConfigurationService extends + SalesManagerEntityService { + + /** + * List all integration modules ready to be used by integrations such as payment and shipping + * @param module + * @return + */ + List getIntegrationModules(String module); + + IntegrationModule getByCode(String moduleCode); + + void createOrUpdateModule(String json) throws ServiceException; + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/system/ModuleConfigurationServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/system/ModuleConfigurationServiceImpl.java new file mode 100755 index 0000000000..d61b8b32ba --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/system/ModuleConfigurationServiceImpl.java @@ -0,0 +1,187 @@ +package com.salesmanager.core.business.services.system; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONArray; +import org.json.simple.JSONValue; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.system.ModuleConfigurationRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.business.services.reference.loader.IntegrationModulesLoader; +import com.salesmanager.core.business.utils.CacheUtils; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.core.model.system.ModuleConfig; + +import modules.commons.ModuleStarter; + +@Service("moduleConfigurationService") +public class ModuleConfigurationServiceImpl extends SalesManagerEntityServiceImpl + implements ModuleConfigurationService { + + private static final Logger LOGGER = LoggerFactory.getLogger(ModuleConfigurationServiceImpl.class); + + @Inject + private IntegrationModulesLoader integrationModulesLoader; + + private ModuleConfigurationRepository moduleConfigurationRepository; + + @Inject + private CacheUtils cache; + + @Autowired(required = false) + private List payments = null; // all bound payment module starters if any + + @Inject + public ModuleConfigurationServiceImpl(ModuleConfigurationRepository moduleConfigurationRepository) { + super(moduleConfigurationRepository); + this.moduleConfigurationRepository = moduleConfigurationRepository; + } + + @Override + public IntegrationModule getByCode(String moduleCode) { + return moduleConfigurationRepository.findByCode(moduleCode); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public List getIntegrationModules(String module) { + + List modules = null; + try { + + /** + * Modules are loaded using + */ + modules = (List) cache.getFromCache("INTEGRATION_M" + module); // PAYMENT_MODULES + // SHIPPING_MODULES + if (modules == null) { + modules = moduleConfigurationRepository.findByModule(module); + // set json objects + for (IntegrationModule mod : modules) { + + String regions = mod.getRegions(); + if (regions != null) { + Object objRegions = JSONValue.parse(regions); + JSONArray arrayRegions = (JSONArray) objRegions; + for (Object arrayRegion : arrayRegions) { + mod.getRegionsSet().add((String) arrayRegion); + } + } + + String details = mod.getConfigDetails(); + if (details != null) { + + Map objDetails = (Map) JSONValue.parse(details); + mod.setDetails(objDetails); + + } + + String configs = mod.getConfiguration(); + if (configs != null) { + + Object objConfigs = JSONValue.parse(configs); + JSONArray arrayConfigs = (JSONArray) objConfigs; + + Map moduleConfigs = new HashMap(); + + for (Object arrayConfig : arrayConfigs) { + + Map values = (Map) arrayConfig; + String env = (String) values.get("env"); + ModuleConfig config = new ModuleConfig(); + config.setScheme((String) values.get("scheme")); + config.setHost((String) values.get("host")); + config.setPort((String) values.get("port")); + config.setUri((String) values.get("uri")); + config.setEnv((String) values.get("env")); + if (values.get("config1") != null) { + config.setConfig1((String) values.get("config1")); + } + if (values.get("config2") != null) { + config.setConfig1((String) values.get("config2")); + } + + moduleConfigs.put(env, config); + + } + + mod.setModuleConfigs(moduleConfigs); + + } + + } + + if (this.payments != null) { + for (ModuleStarter mod : this.payments) { + IntegrationModule m = new IntegrationModule(); + m.setCode(mod.getUniqueCode()); + m.setModule(Constants.PAYMENT_MODULES); + + + if(CollectionUtils.isNotEmpty(mod.getSupportedCountry())) { + m.setRegions(mod.getSupportedCountry().toString()); + m.setRegionsSet(new HashSet(mod.getSupportedCountry())); + } + + if(!StringUtils.isBlank(mod.getLogo())) { + m.setBinaryImage(mod.getLogo());//base 64 + } + + + if(StringUtils.isNotBlank(mod.getConfigurable())) { + m.setConfigurable(mod.getConfigurable()); + } + + modules.add(m); + } + } + + cache.putInCache(modules, "INTEGRATION_M" + module); + } + + } catch (Exception e) { + LOGGER.error("getIntegrationModules()", e); + } + return modules; + + } + + + @Override + public void createOrUpdateModule(String json) throws ServiceException { + + ObjectMapper mapper = new ObjectMapper(); + + try { + @SuppressWarnings("rawtypes") + Map object = mapper.readValue(json, Map.class); + IntegrationModule module = integrationModulesLoader.loadModule(object); + if (module != null) { + IntegrationModule m = this.getByCode(module.getCode()); + if (m != null) { + this.delete(m); + } + this.create(module); + } + } catch (Exception e) { + throw new ServiceException(e); + } + + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/system/SystemConfigurationService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/system/SystemConfigurationService.java new file mode 100755 index 0000000000..6e9ab401ca --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/system/SystemConfigurationService.java @@ -0,0 +1,12 @@ +package com.salesmanager.core.business.services.system; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.system.SystemConfiguration; + +public interface SystemConfigurationService extends + SalesManagerEntityService { + + SystemConfiguration getByKey(String key) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/system/SystemConfigurationServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/system/SystemConfigurationServiceImpl.java new file mode 100755 index 0000000000..bdb5e3b4da --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/system/SystemConfigurationServiceImpl.java @@ -0,0 +1,34 @@ +package com.salesmanager.core.business.services.system; + +import javax.inject.Inject; + +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.system.SystemConfigurationRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.system.SystemConfiguration; + +@Service("systemConfigurationService") +public class SystemConfigurationServiceImpl extends + SalesManagerEntityServiceImpl implements + SystemConfigurationService { + + + private SystemConfigurationRepository systemConfigurationReposotory; + + @Inject + public SystemConfigurationServiceImpl( + SystemConfigurationRepository systemConfigurationReposotory) { + super(systemConfigurationReposotory); + this.systemConfigurationReposotory = systemConfigurationReposotory; + } + + public SystemConfiguration getByKey(String key) throws ServiceException { + return systemConfigurationReposotory.findByKey(key); + } + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/system/optin/OptinService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/system/optin/OptinService.java new file mode 100755 index 0000000000..720d07b712 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/system/optin/OptinService.java @@ -0,0 +1,20 @@ +package com.salesmanager.core.business.services.system.optin; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.system.optin.Optin; +import com.salesmanager.core.model.system.optin.OptinType; + +/** + * Registers Optin events + * @author carlsamson + * + */ +public interface OptinService extends SalesManagerEntityService { + + + Optin getOptinByMerchantAndType(MerchantStore store, OptinType type) throws ServiceException; + Optin getOptinByCode(MerchantStore store, String code) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/system/optin/OptinServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/system/optin/OptinServiceImpl.java new file mode 100755 index 0000000000..2d9fca8dbd --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/system/optin/OptinServiceImpl.java @@ -0,0 +1,37 @@ +package com.salesmanager.core.business.services.system.optin; + +import javax.inject.Inject; + +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.system.OptinRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.system.optin.Optin; +import com.salesmanager.core.model.system.optin.OptinType; + +@Service +public class OptinServiceImpl extends SalesManagerEntityServiceImpl implements OptinService { + + + private OptinRepository optinRepository; + + @Inject + public OptinServiceImpl(OptinRepository optinRepository) { + super(optinRepository); + this.optinRepository = optinRepository; + } + + + @Override + public Optin getOptinByCode(MerchantStore store, String code) throws ServiceException { + return optinRepository.findByMerchantAndCode(store.getId(), code); + } + + @Override + public Optin getOptinByMerchantAndType(MerchantStore store, OptinType type) throws ServiceException { + return optinRepository.findByMerchantAndType(store.getId(), type); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxClassService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxClassService.java new file mode 100755 index 0000000000..27795b03ba --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxClassService.java @@ -0,0 +1,24 @@ +package com.salesmanager.core.business.services.tax; + +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.tax.taxclass.TaxClass; + +public interface TaxClassService extends SalesManagerEntityService { + + List listByStore(MerchantStore store) throws ServiceException; + + TaxClass getByCode(String code) throws ServiceException; + + TaxClass getByCode(String code, MerchantStore store) + throws ServiceException; + + boolean exists(String code, MerchantStore store) throws ServiceException; + + TaxClass saveOrUpdate(TaxClass taxClass) throws ServiceException; + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxClassServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxClassServiceImpl.java new file mode 100755 index 0000000000..38faeea4cb --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxClassServiceImpl.java @@ -0,0 +1,78 @@ +package com.salesmanager.core.business.services.tax; + +import java.util.List; + +import javax.inject.Inject; + +import org.jsoup.helper.Validate; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.tax.TaxClassRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.tax.taxclass.TaxClass; + +@Service("taxClassService") +public class TaxClassServiceImpl extends SalesManagerEntityServiceImpl + implements TaxClassService { + + private TaxClassRepository taxClassRepository; + + @Inject + public TaxClassServiceImpl(TaxClassRepository taxClassRepository) { + super(taxClassRepository); + + this.taxClassRepository = taxClassRepository; + } + + @Override + public List listByStore(MerchantStore store) throws ServiceException { + return taxClassRepository.findByStore(store.getId()); + } + + @Override + public TaxClass getByCode(String code) throws ServiceException { + return taxClassRepository.findByCode(code); + } + + @Override + public TaxClass getByCode(String code, MerchantStore store) throws ServiceException { + return taxClassRepository.findByStoreAndCode(store.getId(), code); + } + + @Override + public void delete(TaxClass taxClass) throws ServiceException { + + TaxClass t = getById(taxClass.getId()); + super.delete(t); + + } + + @Override + public TaxClass getById(Long id) { + return taxClassRepository.getOne(id); + } + + @Override + public boolean exists(String code, MerchantStore store) throws ServiceException { + Validate.notNull(code, "TaxClass code cannot be empty"); + Validate.notNull(store, "MerchantStore cannot be null"); + + return taxClassRepository.findByStoreAndCode(store.getId(), code) != null; + + } + + @Override + public TaxClass saveOrUpdate(TaxClass taxClass) throws ServiceException { + if(taxClass.getId()!=null && taxClass.getId() > 0) { + this.update(taxClass); + } else { + taxClass = super.saveAndFlush(taxClass); + } + return taxClass; + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxRateService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxRateService.java new file mode 100755 index 0000000000..8ff3e4182d --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxRateService.java @@ -0,0 +1,39 @@ +package com.salesmanager.core.business.services.tax; + +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.core.model.tax.taxclass.TaxClass; +import com.salesmanager.core.model.tax.taxrate.TaxRate; + +public interface TaxRateService extends SalesManagerEntityService { + + List listByStore(MerchantStore store) throws ServiceException; + + List listByCountryZoneAndTaxClass(Country country, Zone zone, + TaxClass taxClass, MerchantStore store, Language language) + throws ServiceException; + + List listByCountryStateProvinceAndTaxClass(Country country, + String stateProvince, TaxClass taxClass, MerchantStore store, + Language language) throws ServiceException; + + TaxRate getByCode(String code, MerchantStore store) + throws ServiceException; + + TaxRate getById(Long id, MerchantStore store) + throws ServiceException; + + List listByStore(MerchantStore store, Language language) + throws ServiceException; + + TaxRate saveOrUpdate(TaxRate taxRate) throws ServiceException; + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxRateServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxRateServiceImpl.java new file mode 100755 index 0000000000..7606366cbc --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxRateServiceImpl.java @@ -0,0 +1,84 @@ +package com.salesmanager.core.business.services.tax; + +import java.util.List; + +import javax.inject.Inject; + +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.tax.TaxRateRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.core.model.tax.taxclass.TaxClass; +import com.salesmanager.core.model.tax.taxrate.TaxRate; + +@Service("taxRateService") +public class TaxRateServiceImpl extends SalesManagerEntityServiceImpl + implements TaxRateService { + + private TaxRateRepository taxRateRepository; + + @Inject + public TaxRateServiceImpl(TaxRateRepository taxRateRepository) { + super(taxRateRepository); + this.taxRateRepository = taxRateRepository; + } + + @Override + public List listByStore(MerchantStore store) + throws ServiceException { + return taxRateRepository.findByStore(store.getId()); + } + + @Override + public List listByStore(MerchantStore store, Language language) + throws ServiceException { + return taxRateRepository.findByStoreAndLanguage(store.getId(), language.getId()); + } + + + @Override + public TaxRate getByCode(String code, MerchantStore store) + throws ServiceException { + return taxRateRepository.findByStoreAndCode(store.getId(), code); + } + + @Override + public List listByCountryZoneAndTaxClass(Country country, Zone zone, TaxClass taxClass, MerchantStore store, Language language) throws ServiceException { + return taxRateRepository.findByMerchantAndZoneAndCountryAndLanguage(store.getId(), zone.getId(), country.getId(), language.getId()); + } + + @Override + public List listByCountryStateProvinceAndTaxClass(Country country, String stateProvince, TaxClass taxClass, MerchantStore store, Language language) throws ServiceException { + return taxRateRepository.findByMerchantAndProvinceAndCountryAndLanguage(store.getId(), stateProvince, country.getId(), language.getId()); + } + + @Override + public void delete(TaxRate taxRate) throws ServiceException { + + taxRateRepository.delete(taxRate); + + } + + @Override + public TaxRate saveOrUpdate(TaxRate taxRate) throws ServiceException { + if(taxRate.getId()!=null && taxRate.getId() > 0) { + this.update(taxRate); + } else { + taxRate = super.saveAndFlush(taxRate); + } + return taxRate; + } + + @Override + public TaxRate getById(Long id, MerchantStore store) throws ServiceException { + return taxRateRepository.findByStoreAndId(store.getId(), id); + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxService.java new file mode 100755 index 0000000000..cbc762f693 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxService.java @@ -0,0 +1,47 @@ +package com.salesmanager.core.business.services.tax; + +import java.util.List; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.OrderSummary; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.tax.TaxConfiguration; +import com.salesmanager.core.model.tax.TaxItem; + + +public interface TaxService { + + /** + * Retrieves tax configurations (TaxConfiguration) for a given MerchantStore + * @param store + * @return + * @throws ServiceException + */ + TaxConfiguration getTaxConfiguration(MerchantStore store) + throws ServiceException; + + /** + * Saves ShippingConfiguration to MerchantConfiguration table + * @param shippingConfiguration + * @param store + * @throws ServiceException + */ + void saveTaxConfiguration(TaxConfiguration shippingConfiguration, + MerchantStore store) throws ServiceException; + + /** + * Calculates tax over an OrderSummary + * @param orderSummary + * @param customer + * @param store + * @param locale + * @return + * @throws ServiceException + */ + List calculateTax(OrderSummary orderSummary, Customer customer, + MerchantStore store, Language language) throws ServiceException; + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxServiceImpl.java new file mode 100755 index 0000000000..a0e156223c --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/tax/TaxServiceImpl.java @@ -0,0 +1,302 @@ +package com.salesmanager.core.business.services.tax; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.system.MerchantConfigurationService; +import com.salesmanager.core.model.common.Billing; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.OrderSummary; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.core.model.shipping.ShippingSummary; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.model.system.MerchantConfiguration; +import com.salesmanager.core.model.tax.TaxBasisCalculation; +import com.salesmanager.core.model.tax.TaxConfiguration; +import com.salesmanager.core.model.tax.TaxItem; +import com.salesmanager.core.model.tax.taxclass.TaxClass; +import com.salesmanager.core.model.tax.taxrate.TaxRate; + +@Service("taxService") +public class TaxServiceImpl + implements TaxService { + + private final static String TAX_CONFIGURATION = "TAX_CONFIG"; + private final static String DEFAULT_TAX_CLASS = "DEFAULT"; + + @Inject + private MerchantConfigurationService merchantConfigurationService; + + @Inject + private TaxRateService taxRateService; + + @Inject + private TaxClassService taxClassService; + + @Override + public TaxConfiguration getTaxConfiguration(MerchantStore store) throws ServiceException { + + + + MerchantConfiguration configuration = merchantConfigurationService.getMerchantConfiguration(TAX_CONFIGURATION, store); + TaxConfiguration taxConfiguration = null; + if(configuration!=null) { + String value = configuration.getValue(); + + ObjectMapper mapper = new ObjectMapper(); + try { + taxConfiguration = mapper.readValue(value, TaxConfiguration.class); + } catch(Exception e) { + throw new ServiceException("Cannot parse json string " + value); + } + } + return taxConfiguration; + } + + + @Override + public void saveTaxConfiguration(TaxConfiguration shippingConfiguration, MerchantStore store) throws ServiceException { + + MerchantConfiguration configuration = merchantConfigurationService.getMerchantConfiguration(TAX_CONFIGURATION, store); + + if(configuration==null) { + configuration = new MerchantConfiguration(); + configuration.setMerchantStore(store); + configuration.setKey(TAX_CONFIGURATION); + } + + String value = shippingConfiguration.toJSONString(); + configuration.setValue(value); + merchantConfigurationService.saveOrUpdate(configuration); + + } + + @Override + public List calculateTax(OrderSummary orderSummary, Customer customer, MerchantStore store, Language language) throws ServiceException { + + + if(customer==null) { + return null; + } + + List items = orderSummary.getProducts(); + + List taxLines = new ArrayList(); + + if(items==null) { + return taxLines; + } + + //determine tax calculation basis + TaxConfiguration taxConfiguration = this.getTaxConfiguration(store); + if(taxConfiguration==null) { + taxConfiguration = new TaxConfiguration(); + taxConfiguration.setTaxBasisCalculation(TaxBasisCalculation.SHIPPINGADDRESS); + } + + Country country = customer.getBilling().getCountry(); + Zone zone = customer.getBilling().getZone(); + String stateProvince = customer.getBilling().getState(); + + TaxBasisCalculation taxBasisCalculation = taxConfiguration.getTaxBasisCalculation(); + if(taxBasisCalculation.name().equals(TaxBasisCalculation.SHIPPINGADDRESS)){ + Delivery shipping = customer.getDelivery(); + if(shipping!=null) { + country = shipping.getCountry(); + zone = shipping.getZone(); + stateProvince = shipping.getState(); + } + } else if(taxBasisCalculation.name().equals(TaxBasisCalculation.BILLINGADDRESS)){ + Billing billing = customer.getBilling(); + if(billing!=null) { + country = billing.getCountry(); + zone = billing.getZone(); + stateProvince = billing.getState(); + } + } else if(taxBasisCalculation.name().equals(TaxBasisCalculation.STOREADDRESS)){ + country = store.getCountry(); + zone = store.getZone(); + stateProvince = store.getStorestateprovince(); + } + + //check other conditions + //do not collect tax on other provinces of same country + if(!taxConfiguration.isCollectTaxIfDifferentProvinceOfStoreCountry()) { + if((zone!=null && store.getZone()!=null) && (zone.getId().longValue() != store.getZone().getId().longValue())) { + return null; + } + if(!StringUtils.isBlank(stateProvince)) { + if(store.getZone()!=null) { + if(!store.getZone().getName().equals(stateProvince)) { + return null; + } + } + else if(!StringUtils.isBlank(store.getStorestateprovince())) { + + if(!store.getStorestateprovince().equals(stateProvince)) { + return null; + } + } + } + } + + //collect tax in different countries + if(taxConfiguration.isCollectTaxIfDifferentCountryOfStoreCountry()) { + //use store country + country = store.getCountry(); + zone = store.getZone(); + stateProvince = store.getStorestateprovince(); + } + + if(zone == null && StringUtils.isBlank(stateProvince)) { + return null; + } + + Map taxClasses = new HashMap(); + + //put items in a map by tax class id + Map taxClassAmountMap = new HashMap(); + for(ShoppingCartItem item : items) { + + BigDecimal itemPrice = item.getItemPrice(); + TaxClass taxClass = item.getProduct().getTaxClass(); + int quantity = item.getQuantity(); + itemPrice = itemPrice.multiply(new BigDecimal(quantity)); + if(taxClass==null) { + taxClass = taxClassService.getByCode(DEFAULT_TAX_CLASS); + } + BigDecimal subTotal = taxClassAmountMap.get(taxClass.getId()); + if(subTotal==null) { + subTotal = new BigDecimal(0); + subTotal.setScale(2, RoundingMode.HALF_UP); + } + + subTotal = subTotal.add(itemPrice); + taxClassAmountMap.put(taxClass.getId(), subTotal); + taxClasses.put(taxClass.getId(), taxClass); + + } + + //tax on shipping ? + //ShippingConfiguration shippingConfiguration = shippingService.getShippingConfiguration(store); + + /** always calculate tax on shipping **/ + //if(shippingConfiguration!=null) { + //if(shippingConfiguration.isTaxOnShipping()){ + //use default tax class for shipping + TaxClass defaultTaxClass = taxClassService.getByCode(TaxClass.DEFAULT_TAX_CLASS); + //taxClasses.put(defaultTaxClass.getId(), defaultTaxClass); + BigDecimal amnt = taxClassAmountMap.get(defaultTaxClass.getId()); + if(amnt==null) { + amnt = new BigDecimal(0); + amnt.setScale(2, RoundingMode.HALF_UP); + } + ShippingSummary shippingSummary = orderSummary.getShippingSummary(); + if(shippingSummary!=null && shippingSummary.getShipping()!=null && shippingSummary.getShipping().doubleValue()>0) { + amnt = amnt.add(shippingSummary.getShipping()); + if(shippingSummary.getHandling()!=null && shippingSummary.getHandling().doubleValue()>0) { + amnt = amnt.add(shippingSummary.getHandling()); + } + } + taxClassAmountMap.put(defaultTaxClass.getId(), amnt); + //} + //} + + + List taxItems = new ArrayList(); + + //iterate through the tax class and get appropriate rates + for(Long taxClassId : taxClassAmountMap.keySet()) { + + //get taxRate by tax class + List taxRates = null; + if(!StringUtils.isBlank(stateProvince)&& zone==null) { + taxRates = taxRateService.listByCountryStateProvinceAndTaxClass(country, stateProvince, taxClasses.get(taxClassId), store, language); + } else { + taxRates = taxRateService.listByCountryZoneAndTaxClass(country, zone, taxClasses.get(taxClassId), store, language); + } + + if(taxRates==null || taxRates.size()==0){ + continue; + } + BigDecimal taxedItemValue = null; + BigDecimal totalTaxedItemValue = new BigDecimal(0); + totalTaxedItemValue.setScale(2, RoundingMode.HALF_UP); + BigDecimal beforeTaxeAmount = taxClassAmountMap.get(taxClassId); + for(TaxRate taxRate : taxRates) { + + double taxRateDouble = taxRate.getTaxRate().doubleValue();//5% ... 8% ... + + + if(taxRate.isPiggyback()) {//(compound) + if(totalTaxedItemValue.doubleValue()>0) { + beforeTaxeAmount = totalTaxedItemValue; + } + } //else just use nominal taxing (combine) + + double value = (beforeTaxeAmount.doubleValue() * taxRateDouble)/100; + double roundedValue = new BigDecimal(value).setScale(2, RoundingMode.HALF_UP).doubleValue(); + taxedItemValue = new BigDecimal(roundedValue).setScale(2, RoundingMode.HALF_UP); + totalTaxedItemValue = beforeTaxeAmount.add(taxedItemValue); + + TaxItem taxItem = new TaxItem(); + taxItem.setItemPrice(taxedItemValue); + taxItem.setLabel(taxRate.getDescriptions().get(0).getName()); + taxItem.setTaxRate(taxRate); + taxItems.add(taxItem); + + } + + } + + + + Map taxItemsMap = new TreeMap(); + //consolidate tax rates of same code + for(TaxItem taxItem : taxItems) { + + TaxRate taxRate = taxItem.getTaxRate(); + if(!taxItemsMap.containsKey(taxRate.getCode())) { + taxItemsMap.put(taxRate.getCode(), taxItem); + } + + TaxItem item = taxItemsMap.get(taxRate.getCode()); + BigDecimal amount = item.getItemPrice(); + amount = amount.add(taxItem.getItemPrice()); + + } + + if(taxItemsMap.size()==0) { + return null; + } + + + @SuppressWarnings("rawtypes") + Collection values = taxItemsMap.values(); + + + @SuppressWarnings("unchecked") + List list = new ArrayList(values); + return list; + + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/user/GroupService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/user/GroupService.java new file mode 100755 index 0000000000..3abf899a43 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/user/GroupService.java @@ -0,0 +1,20 @@ +package com.salesmanager.core.business.services.user; + +import java.util.List; +import java.util.Set; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.model.user.GroupType; + + +public interface GroupService extends SalesManagerEntityService { + + + List listGroup(GroupType groupType) throws ServiceException; + List listGroupByIds(Set ids) throws ServiceException; + List listGroupByNames(List names) throws ServiceException; + Group findByName(String groupName) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/user/GroupServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/user/GroupServiceImpl.java new file mode 100755 index 0000000000..de6246e9ee --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/user/GroupServiceImpl.java @@ -0,0 +1,62 @@ +package com.salesmanager.core.business.services.user; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import javax.inject.Inject; +import org.springframework.stereotype.Service; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.user.GroupRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.model.user.GroupType; + + +@Service("groupService") +public class GroupServiceImpl extends SalesManagerEntityServiceImpl + implements GroupService { + + GroupRepository groupRepository; + + + @Inject + public GroupServiceImpl(GroupRepository groupRepository) { + super(groupRepository); + this.groupRepository = groupRepository; + + } + + + @Override + public List listGroup(GroupType groupType) throws ServiceException { + try { + return groupRepository.findByType(groupType); + } catch (Exception e) { + throw new ServiceException(e); + } + } + + public List listGroupByIds(Set ids) throws ServiceException { + + try { + return ids.isEmpty() ? new ArrayList() : groupRepository.findByIds(ids); + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + + @Override + public Group findByName(String groupName) throws ServiceException { + return groupRepository.findByGroupName(groupName); + } + + + @Override + public List listGroupByNames(List names) throws ServiceException { + return groupRepository.findByNames(names); + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/user/PermissionService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/user/PermissionService.java new file mode 100755 index 0000000000..eaefd804e5 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/user/PermissionService.java @@ -0,0 +1,29 @@ +package com.salesmanager.core.business.services.user; + +import java.util.List; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.model.user.Permission; +import com.salesmanager.core.model.user.PermissionCriteria; +import com.salesmanager.core.model.user.PermissionList; + + + +public interface PermissionService extends SalesManagerEntityService { + + List getByName(); + + List listPermission() throws ServiceException; + + Permission getById(Integer permissionId); + + List getPermissions(List groupIds) throws ServiceException; + + void deletePermission(Permission permission) throws ServiceException; + + PermissionList listByCriteria(PermissionCriteria criteria) throws ServiceException; + + void removePermission(Permission permission, Group group) throws ServiceException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/user/PermissionServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/user/PermissionServiceImpl.java new file mode 100755 index 0000000000..b2c8ed0ce4 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/user/PermissionServiceImpl.java @@ -0,0 +1,90 @@ +package com.salesmanager.core.business.services.user; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.inject.Inject; + +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.user.PermissionRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.model.user.Permission; +import com.salesmanager.core.model.user.PermissionCriteria; +import com.salesmanager.core.model.user.PermissionList; + + + +@Service("permissionService") +public class PermissionServiceImpl extends + SalesManagerEntityServiceImpl implements + PermissionService { + + private PermissionRepository permissionRepository; + + + @Inject + public PermissionServiceImpl(PermissionRepository permissionRepository) { + super(permissionRepository); + this.permissionRepository = permissionRepository; + + } + + @Override + public List getByName() { + // TODO Auto-generated method stub + return null; + } + + + @Override + public Permission getById(Integer permissionId) { + return permissionRepository.findOne(permissionId); + + } + + + @Override + public void deletePermission(Permission permission) throws ServiceException { + permission = this.getById(permission.getId());//Prevents detached entity error + permission.setGroups(null); + + this.delete(permission); + } + + + @SuppressWarnings("unchecked") + @Override + public List getPermissions(List groupIds) + throws ServiceException { + @SuppressWarnings({ "unchecked", "rawtypes" }) + Set ids = new HashSet(groupIds); + return permissionRepository.findByGroups(ids); + } + + @Override + public PermissionList listByCriteria(PermissionCriteria criteria) + throws ServiceException { + return permissionRepository.listByCriteria(criteria); + } + + @Override + public void removePermission(Permission permission,Group group) throws ServiceException { + permission = this.getById(permission.getId());//Prevents detached entity error + + permission.getGroups().remove(group); + + + } + + @Override + public List listPermission() throws ServiceException { + return permissionRepository.findAll(); + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/user/UserService.java b/sm-core/src/main/java/com/salesmanager/core/business/services/user/UserService.java new file mode 100755 index 0000000000..bd8bf4f319 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/user/UserService.java @@ -0,0 +1,50 @@ +package com.salesmanager.core.business.services.user; + +import java.util.List; + +import org.springframework.data.domain.Page; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityService; +import com.salesmanager.core.model.common.Criteria; +import com.salesmanager.core.model.common.GenericEntityList; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.user.User; +import com.salesmanager.core.model.user.UserCriteria; + + + +public interface UserService extends SalesManagerEntityService { + + User getByUserName(String userName) throws ServiceException; + User getByUserName(String userName, String storeCode) throws ServiceException; + + List listUser() throws ServiceException; + + User getById(Long id, MerchantStore store); + + User getByPasswordResetToken(String storeCode, String token); + + /** + * Create or update a User + * + * @param user + * @throws ServiceException + */ + void saveOrUpdate(User user) throws ServiceException; + + List listByStore(MerchantStore store) throws ServiceException; + + User findByStore(Long userId, String storeCode) throws ServiceException; + + @Deprecated + GenericEntityList listByCriteria(Criteria criteria) throws ServiceException; + + Page listByCriteria(UserCriteria criteria, int page, int count) throws ServiceException; + + User findByResetPasswordToken (String userName, String token, MerchantStore store) throws ServiceException; + + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/services/user/UserServiceImpl.java b/sm-core/src/main/java/com/salesmanager/core/business/services/user/UserServiceImpl.java new file mode 100755 index 0000000000..dd14409b39 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/services/user/UserServiceImpl.java @@ -0,0 +1,141 @@ +package com.salesmanager.core.business.services.user; + +import java.util.List; +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.repositories.user.PageableUserRepository; +import com.salesmanager.core.business.repositories.user.UserRepository; +import com.salesmanager.core.business.services.common.generic.SalesManagerEntityServiceImpl; +import com.salesmanager.core.business.services.merchant.MerchantStoreService; +import com.salesmanager.core.model.common.Criteria; +import com.salesmanager.core.model.common.GenericEntityList; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.user.User; +import com.salesmanager.core.model.user.UserCriteria; + +public class UserServiceImpl extends SalesManagerEntityServiceImpl implements UserService { + + private UserRepository userRepository; + + @Autowired + private MerchantStoreService merchantStoreService; + + @Autowired + private PageableUserRepository pageableUserRepository; + + @Inject + public UserServiceImpl(UserRepository userRepository) { + super(userRepository); + this.userRepository = userRepository; + + } + + @Override + public User getByUserName(String userName) throws ServiceException { + return userRepository.findByUserName(userName); + } + + @Override + public void delete(User user) throws ServiceException { + User u = this.getById(user.getId()); + super.delete(u); + + } + + @Override + public List listUser() throws ServiceException { + try { + return userRepository.findAll(); + } catch (Exception e) { + throw new ServiceException(e); + } + } + + @Override + public List listByStore(MerchantStore store) throws ServiceException { + try { + return userRepository.findByStore(store.getId()); + } catch (Exception e) { + throw new ServiceException(e); + } + } + + @Override + public void saveOrUpdate(User user) throws ServiceException { + userRepository.save(user); + } + + @Override + public User findByStore(Long userId, String storeCode) throws ServiceException { + + User user = userRepository.findOne(userId); + + // store must be in lineage + boolean isFound = merchantStoreService.isStoreInGroup(storeCode); + + if (isFound) + return user; + + return null; + + } + + @Override + public GenericEntityList listByCriteria(Criteria criteria) throws ServiceException { + return userRepository.listByCriteria(criteria); + } + + @Override + public User getByUserName(String userName, String storeCode) throws ServiceException { + return userRepository.findByUserName(userName, storeCode); + } + + @Override + public Page listByCriteria(UserCriteria criteria, int page, int count) throws ServiceException { + + Pageable pageRequest = PageRequest.of(page, count); + Page users = null; + if (criteria.getStoreIds() != null) {// search within a predefined list + // of stores + users = pageableUserRepository.listByStoreIds(criteria.getStoreIds(), criteria.getAdminEmail(), + pageRequest); + } else if (StringUtils.isBlank(criteria.getStoreCode())) {// search for + // a + // specific + // store + users = pageableUserRepository.listAll(criteria.getAdminEmail(), pageRequest); + } else if (criteria.getStoreCode() != null) {// store code + users = pageableUserRepository.listByStore(criteria.getStoreCode(), criteria.getAdminEmail(), pageRequest); + } + + return users; + } + + @Override + public User getById(Long id, MerchantStore store) { + Validate.notNull(store, "MerchantStore cannot be null"); + return userRepository.findByUserId(id, store.getCode()); + } + + @Override + public User findByResetPasswordToken(String userName, String token, MerchantStore store) throws ServiceException { + Validate.notNull(userName, "User name cannot be null"); + Validate.notNull(token, "Token cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + return null; + } + + @Override + public User getByPasswordResetToken(String storeCode, String token) { + return userRepository.findByResetPasswordToken(token, storeCode); + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/utils/AbstractDataPopulator.java b/sm-core/src/main/java/com/salesmanager/core/business/utils/AbstractDataPopulator.java new file mode 100755 index 0000000000..3a8eba4a1d --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/utils/AbstractDataPopulator.java @@ -0,0 +1,41 @@ +/** + * + */ +package com.salesmanager.core.business.utils; + +import java.util.Locale; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + + +/** + * @author Umesh A + * + */ +public abstract class AbstractDataPopulator implements DataPopulator +{ + + + + private Locale locale; + + public void setLocale(Locale locale) { + this.locale = locale; + } + public Locale getLocale() { + return locale; + } + + + + @Override + public Target populate(Source source, MerchantStore store, Language language) throws ConversionException{ + return populate(source,createTarget(), store, language); + } + protected abstract Target createTarget(); + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/utils/CacheUtils.java b/sm-core/src/main/java/com/salesmanager/core/business/utils/CacheUtils.java new file mode 100755 index 0000000000..8b48e3dbaa --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/utils/CacheUtils.java @@ -0,0 +1,112 @@ +package com.salesmanager.core.business.utils; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.cache.Cache; +import org.springframework.cache.Cache.ValueWrapper; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.merchant.MerchantStore; + +@Component("cache") +public class CacheUtils { + + + @Inject + @Qualifier("serviceCache") + private Cache cache; + + + public final static String REFERENCE_CACHE = "REF"; + + private static final Logger LOGGER = LoggerFactory.getLogger(CacheUtils.class); + + private final static String KEY_DELIMITER = "_"; + + + + public void putInCache(Object object, String keyName) throws Exception { + + cache.put(keyName, object); + + } + + + public Object getFromCache(String keyName) throws Exception { + + ValueWrapper vw = cache.get(keyName); + if(vw!=null) { + return vw.get(); + } + + return null; + + } + + public List getCacheKeys(MerchantStore store) throws Exception { + + net.sf.ehcache.Cache cacheImpl = (net.sf.ehcache.Cache) cache.getNativeCache(); + List returnKeys = new ArrayList(); + for (Object key: cacheImpl.getKeys()) { + + + try { + String sKey = (String)key; + + // a key should be _ + int delimiterPosition = sKey.indexOf(KEY_DELIMITER); + + if(delimiterPosition>0 && Character.isDigit(sKey.charAt(0))) { + + String keyRemaining = sKey.substring(delimiterPosition+1); + returnKeys.add(keyRemaining); + + } + + } catch (Exception e) { + LOGGER.equals("key " + key + " cannot be converted to a String or parsed"); + } + } + + return returnKeys; + } + + public void shutDownCache() throws Exception { + + } + + public void removeFromCache(String keyName) throws Exception { + cache.evict(keyName); + } + + public void removeAllFromCache(MerchantStore store) throws Exception { + net.sf.ehcache.Cache cacheImpl = (net.sf.ehcache.Cache) cache.getNativeCache(); + for (Object key: cacheImpl.getKeys()) { + try { + String sKey = (String)key; + + // a key should be _ + int delimiterPosition = sKey.indexOf(KEY_DELIMITER); + + if(delimiterPosition>0 && Character.isDigit(sKey.charAt(0))) { + + + cache.evict(key); + + } + + } catch (Exception e) { + LOGGER.equals("key " + key + " cannot be converted to a String or parsed"); + } + } + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/utils/CatalogServiceHelper.java b/sm-core/src/main/java/com/salesmanager/core/business/utils/CatalogServiceHelper.java new file mode 100755 index 0000000000..eeffe4b90a --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/utils/CatalogServiceHelper.java @@ -0,0 +1,73 @@ +package com.salesmanager.core.business.utils; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.*; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; + +import java.util.HashSet; +import java.util.Locale; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + + +public class CatalogServiceHelper { + + /** + * Filters descriptions and set the appropriate language + * + * @param p + * @param language + */ + public static void setToLanguage(Product p, int language) { + + + Set attributes = p.getAttributes(); + if (attributes != null) { + + for (ProductAttribute attribute : attributes) { + + ProductOption po = attribute.getProductOption(); + if (po.getDescriptions() != null) { + Set podDescriptions = po.getDescriptions().stream().filter(pod -> pod.getLanguage().getId() == language).collect(Collectors.toSet()); + po.setDescriptions(podDescriptions); + } + + ProductOptionValue pov = attribute.getProductOptionValue(); + if (pov.getDescriptions() != null) { + Set povdDescriptions = pov.getDescriptions().stream().filter(pod -> pod.getLanguage().getId() == language).collect(Collectors.toSet()); + pov.setDescriptions(povdDescriptions); + } + } + } + + } + + /** + * Overwrites the availability in order to return 1 price / region + * + * @param product + * @param locale + */ + public static void setToAvailability(Product product, Locale locale) { + + Set availabilities = product.getAvailabilities(); + Set productAvailabilities = new HashSet(); + + Optional defaultAvailability = availabilities.stream().filter(productAvailability -> productAvailability.getRegion().equals(Constants.ALL_REGIONS)).findFirst(); + Optional localeAvailability = availabilities.stream().filter(productAvailability -> productAvailability.getRegion().equals(locale.getCountry())).findFirst(); + if (defaultAvailability.isPresent()) { + productAvailabilities.add(defaultAvailability.get()); + } + if (localeAvailability.isPresent()) { + productAvailabilities.add(localeAvailability.get()); + } + + if (productAvailabilities.isEmpty()) { + product.setAvailabilities(productAvailabilities); + + } + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/utils/CoreConfiguration.java b/sm-core/src/main/java/com/salesmanager/core/business/utils/CoreConfiguration.java new file mode 100755 index 0000000000..d8809a4395 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/utils/CoreConfiguration.java @@ -0,0 +1,46 @@ +package com.salesmanager.core.business.utils; + +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class CoreConfiguration { + + + public Properties properties = new Properties(); + private static final Logger LOGGER = LoggerFactory.getLogger(CoreConfiguration.class); + + public Properties getProperties() { + return properties; + } + + public void setProperties(Properties properties) { + this.properties = properties; + } + + public CoreConfiguration() {} + + public String getProperty(String propertyKey) { + + return properties.getProperty(propertyKey); + + + } + + public String getProperty(String propertyKey, String defaultValue) { + + String prop = defaultValue; + try { + prop = properties.getProperty(propertyKey); + } catch(Exception e) { + LOGGER.warn("Cannot find property " + propertyKey); + } + return prop; + + + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/utils/CreditCardUtils.java b/sm-core/src/main/java/com/salesmanager/core/business/utils/CreditCardUtils.java new file mode 100755 index 0000000000..393e273fd9 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/utils/CreditCardUtils.java @@ -0,0 +1,28 @@ +package com.salesmanager.core.business.utils; + +@Deprecated +public class CreditCardUtils { + + + public static final int MASTERCARD = 0, VISA = 1; + public static final int AMEX = 2, DISCOVER = 3, DINERS = 4; + + public static String maskCardNumber(String clearcardnumber) + throws Exception { + + if (clearcardnumber.length() < 10) { + throw new Exception("Invalid number of digits"); + } + + int length = clearcardnumber.length(); + + String prefix = clearcardnumber.substring(0, 4); + String suffix = clearcardnumber.substring(length - 4); + + return new StringBuilder() + .append(prefix) + .append("XXXXXXXXXX") + .append(suffix) + .toString(); + } +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/utils/DataPopulator.java b/sm-core/src/main/java/com/salesmanager/core/business/utils/DataPopulator.java new file mode 100755 index 0000000000..7affb49249 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/utils/DataPopulator.java @@ -0,0 +1,19 @@ +/** + * + */ +package com.salesmanager.core.business.utils; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +/** + * @author Umesh A + * + */ +public interface DataPopulator { + + Target populate(Source source,Target target, MerchantStore store, Language language) throws ConversionException; + Target populate(Source source, MerchantStore store, Language language) throws ConversionException; + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/utils/DataUtils.java b/sm-core/src/main/java/com/salesmanager/core/business/utils/DataUtils.java new file mode 100755 index 0000000000..b254ccae56 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/utils/DataUtils.java @@ -0,0 +1,97 @@ +package com.salesmanager.core.business.utils; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +import com.salesmanager.core.constants.MeasureUnit; +import com.salesmanager.core.model.merchant.MerchantStore; + +public class DataUtils { + + /** + * Removes dashes + * @param postalCode + * @return + */ + public static String trimPostalCode(String postalCode) { + return postalCode.replaceAll("[^a-zA-Z0-9]", ""); + } + + + /** + * Get the measure according to the appropriate measure base. If the measure + * configured in store is LB and it needs KG then the appropriate + * calculation is done + * + * @param weight + * @param store + * @param base + * @return + */ + public static double getWeight(double weight, MerchantStore store, + String base) { + + double weightConstant = 2.2; + if (base.equals(MeasureUnit.LB.name())) { + if (store.getWeightunitcode().equals(MeasureUnit.LB.name())) { + return new BigDecimal(String.valueOf(weight)) + .setScale(2, RoundingMode.HALF_UP).doubleValue(); + } else {// pound = kilogram + double answer = weight * weightConstant; + BigDecimal w = new BigDecimal(answer); + return w.setScale(2, RoundingMode.HALF_UP).doubleValue(); + } + } else {// need KG + if (store.getWeightunitcode().equals(MeasureUnit.KG.name())) { + return new BigDecimal(String.valueOf(weight)).setScale(2, + RoundingMode.HALF_UP).doubleValue(); + } else { + double answer = weight / weightConstant; + BigDecimal w = new BigDecimal(answer); + return w.setScale(2, RoundingMode.HALF_UP).doubleValue(); + } + } + } + + /** + * Get the measure according to the appropriate measure base. If the measure + * configured in store is IN and it needs CM or vise versa then the + * appropriate calculation is done + * + * @param weight + * @param store + * @param base + * @return + */ + public static double getMeasure(double measure, MerchantStore store, + String base) { + + if (base.equals(MeasureUnit.IN.name())) { + if (store.getSeizeunitcode().equals(MeasureUnit.IN.name())) { + return new BigDecimal(String.valueOf(measure)).setScale(2, + RoundingMode.HALF_UP).doubleValue(); + } else {// centimeter (inch to centimeter) + double measureConstant = 2.54; + + double answer = measure * measureConstant; + BigDecimal w = new BigDecimal(answer); + return w.setScale(2, RoundingMode.HALF_UP).doubleValue(); + + } + } else {// need CM + if (store.getSeizeunitcode().equals(MeasureUnit.CM.name())) { + return new BigDecimal(String.valueOf(measure)).setScale(2, + RoundingMode.HALF_UP).doubleValue(); + } else {// in (centimeter to inch) + double measureConstant = 0.39; + + double answer = measure * measureConstant; + BigDecimal w = new BigDecimal(answer); + return w.setScale(2, RoundingMode.HALF_UP).doubleValue(); + + } + } + + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/utils/EntityPopulator.java b/sm-core/src/main/java/com/salesmanager/core/business/utils/EntityPopulator.java new file mode 100755 index 0000000000..30b13e85e6 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/utils/EntityPopulator.java @@ -0,0 +1,18 @@ +/** + * + */ +package com.salesmanager.core.business.utils; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.model.merchant.MerchantStore; + +/** + * @author Umesh A + * + */ +public interface EntityPopulator +{ + + Target populateToEntity(Source source, Target target, MerchantStore store) throws ConversionException; + Target populateToEntity(Source source) throws ConversionException; +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/utils/NumberUtils.java b/sm-core/src/main/java/com/salesmanager/core/business/utils/NumberUtils.java new file mode 100644 index 0000000000..b27031c1fd --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/utils/NumberUtils.java @@ -0,0 +1,10 @@ +package com.salesmanager.core.business.utils; + +import java.util.Objects; + +public final class NumberUtils { + + public static boolean isPositive(Long id) { + return Objects.nonNull(id) && id > 0; + } +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/utils/ProductImageCropUtils.java b/sm-core/src/main/java/com/salesmanager/core/business/utils/ProductImageCropUtils.java new file mode 100755 index 0000000000..d98f941b27 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/utils/ProductImageCropUtils.java @@ -0,0 +1,230 @@ +package com.salesmanager.core.business.utils; + +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.net.FileNameMap; +import java.net.URLConnection; + +import javax.imageio.ImageIO; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ProductImageCropUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductImageCropUtils.class); + + private boolean cropeable = true; + + private int cropeBaseline = 0;// o is width, 1 is height + + private int getCropeBaseline() { + return cropeBaseline; + } + + + + private double cropAreaWidth = 0; + private double cropAreaHeight = 0; + + //private InputStream originalFile = null; + private BufferedImage originalFile = null; + + + + public ProductImageCropUtils(BufferedImage file, int largeImageWidth, int largeImageHeight) { + + + + try { + + + this.originalFile = file; + + /** Original Image **/ + // get original image size + + int width = originalFile.getWidth(); + int height = originalFile.getHeight(); + + /*** determine if image can be cropped ***/ + determineCropeable(width, largeImageWidth, height, largeImageHeight); + + /*** determine crop area calculation baseline ***/ + //this.determineBaseline(width, height); + + determineCropArea(width, largeImageWidth, height, largeImageHeight); + + } catch (Exception e) { + LOGGER.error("Image Utils error in constructor", e); + } + + + + + + + } + + + private void determineCropeable(int width, int specificationsWidth, + int height, int specificationsHeight) { + /*** determine if image can be cropped ***/ + // height + int y = height - specificationsHeight; + // width + int x = width - specificationsWidth; + + if (x < 0 || y < 0) { + setCropeable(false); + } + + if (x == 0 && y == 0) { + setCropeable(false); + } + + + if((height % specificationsHeight) == 0 && (width % specificationsWidth) == 0 ) { + setCropeable(false); + } + + + + } + + + private void determineCropArea(int width, int specificationsWidth, + int height, int specificationsHeight) { + + cropAreaWidth = specificationsWidth; + cropAreaHeight = specificationsHeight; + + + double factorWidth = Integer.valueOf(width).doubleValue() / Integer.valueOf(specificationsWidth).doubleValue(); + double factorHeight = Integer.valueOf(height).doubleValue() / Integer.valueOf(specificationsHeight).doubleValue(); + + double factor = factorWidth; + + if(factorWidth>factorHeight) { + factor = factorHeight; + } + + + // crop factor +/* double factor = 1; + if (this.getCropeBaseline() == 0) {// width + factor = new Integer(width).doubleValue() + / new Integer(specificationsWidth).doubleValue(); + } else {// height + factor = new Integer(height).doubleValue() + / new Integer(specificationsHeight).doubleValue(); + }*/ + + double w = factor * specificationsWidth; + double h = factor * specificationsHeight; + + if(w==h) { + setCropeable(false); + } + + + cropAreaWidth = w; + + if(cropAreaWidth > width) + cropAreaWidth = width; + + cropAreaHeight = h; + + if(cropAreaHeight > height) + cropAreaHeight = height; + + /* + * if(factor>1) { //determine croping section for(double + * i=factor;i>1;i--) { //multiply specifications by factor int newWidth + * = (int)(i * specificationsWidth); int newHeight = (int)(i * + * specificationsHeight); //check if new size >= original image + * if(width>=newWidth && height>=newHeight) { cropAreaWidth = newWidth; + * cropAreaHeight = newHeight; break; } } } + */ + + } + + + public File getCroppedImage(File originalFile, int x1, int y1, int width, + int height) throws Exception { + + if(!this.cropeable) { + return originalFile; + } + + FileNameMap fileNameMap = URLConnection.getFileNameMap(); + String contentType = fileNameMap.getContentTypeFor(originalFile.getName()); + + String extension = contentType.substring(contentType.indexOf("/"),contentType.length()); + + BufferedImage image = ImageIO.read(originalFile); + BufferedImage out = image.getSubimage(x1, y1, width, height); + File tempFile = File.createTempFile("temp", "." + extension ); + tempFile.deleteOnExit(); + ImageIO.write(out, extension, tempFile); + return tempFile; + } + + public BufferedImage getCroppedImage() throws IOException { + + + //out if croppedArea == 0 or file is null + + + + + Rectangle goal = new Rectangle( (int)this.getCropAreaWidth(), (int) this.getCropAreaHeight()); + + //Then intersect it with the dimensions of your image: + + Rectangle clip = goal.intersection(new Rectangle(originalFile.getWidth(), originalFile.getHeight())); + + //Now, clip corresponds to the portion of bi that will fit within your goal. In this case 100 x50. + + //Now get the subImage using the value of clip. + + + return originalFile.getSubimage(clip.x, clip.y, clip.width, clip.height); + + + + + } + + + + + public double getCropAreaWidth() { + return cropAreaWidth; + } + + public void setCropAreaWidth(int cropAreaWidth) { + this.cropAreaWidth = cropAreaWidth; + } + + public double getCropAreaHeight() { + return cropAreaHeight; + } + + public void setCropAreaHeight(int cropAreaHeight) { + this.cropAreaHeight = cropAreaHeight; + } + + public void setCropeable(boolean cropeable) { + this.cropeable = cropeable; + } + + public boolean isCropeable() { + return cropeable; + } + + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/utils/ProductImageSizeUtils.java b/sm-core/src/main/java/com/salesmanager/core/business/utils/ProductImageSizeUtils.java new file mode 100755 index 0000000000..83249e46c0 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/utils/ProductImageSizeUtils.java @@ -0,0 +1,151 @@ +package com.salesmanager.core.business.utils; + +import java.awt.AlphaComposite; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.Transparency; +import java.awt.image.BufferedImage; + +/** + * Utility class for image resize functions + * @author Carl Samson + * + */ +public class ProductImageSizeUtils { + + + private ProductImageSizeUtils() { + + } + + + /** + * Simple resize, does not maintain aspect ratio + * @param image + * @param width + * @param height + * @return + */ + + public static BufferedImage resize(BufferedImage image, int width, int height) { + int type = image.getType() == 0 ? BufferedImage.TYPE_INT_ARGB : image + .getType(); + BufferedImage resizedImage = new BufferedImage(width, height, type); + Graphics2D g = resizedImage.createGraphics(); + g.setComposite(AlphaComposite.Src); + g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_BILINEAR); + g.setRenderingHint(RenderingHints.KEY_RENDERING, + RenderingHints.VALUE_RENDER_QUALITY); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g.drawImage(image, 0, 0, width, height, null); + g.dispose(); + return resizedImage; + } + + /** + * + * @param img + * @param targetWidth + * @param targetHeight + * @param hint + * {@code RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR}, + * {@code RenderingHints.VALUE_INTERPOLATION_BILINEAR}, + * {@code RenderingHints.VALUE_INTERPOLATION_BICUBIC}) + * @param higherQuality + * @return + */ + public static BufferedImage resizeWithHint(BufferedImage img, + int targetWidth, int targetHeight, Object hint, + boolean higherQuality) { + int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB + : BufferedImage.TYPE_INT_ARGB; + BufferedImage ret = img; + int w, h; + if (higherQuality) { + // Use multi-step technique: start with original size, then + // scale down in multiple passes with drawImage() + // until the target size is reached + w = img.getWidth(); + h = img.getHeight(); + } else { + // Use one-step technique: scale directly from original + // size to target size with a single drawImage() call + w = targetWidth; + h = targetHeight; + } + + do { + if (higherQuality && w > targetWidth) { + w /= 2; + if (w < targetWidth) { + w = targetWidth; + } + } + + if (higherQuality && h > targetHeight) { + h /= 2; + if (h < targetHeight) { + h = targetHeight; + } + } + + BufferedImage tmp = new BufferedImage(w, h, type); + Graphics2D g2 = tmp.createGraphics(); + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); + g2.drawImage(ret, 0, 0, w, h, null); + g2.dispose(); + + ret = tmp; + } while (w != targetWidth || h != targetHeight); + + return ret; + } + + + public static BufferedImage resizeWithRatio(BufferedImage image, int destinationWidth, int destinationHeight) { + + int type = image.getType() == 0? BufferedImage.TYPE_INT_ARGB : image.getType(); + + //*Special* if the width or height is 0 use image src dimensions + if (destinationWidth == 0) { + destinationWidth = image.getWidth(); + } + if (destinationHeight == 0) { + destinationHeight = image.getHeight(); + } + + int fHeight = destinationHeight; + int fWidth = destinationWidth; + + //Work out the resized width/height + if (image.getHeight() > destinationHeight || image.getWidth() > destinationWidth) { + if (image.getHeight() > image.getWidth()) { + fHeight = destinationHeight; + float sum = (float) image.getWidth() / (float) image.getHeight(); + fWidth = Math.round(destinationWidth * sum); + } else if (image.getWidth() > image.getHeight()) { + fWidth = destinationWidth; + float sum = (float) image.getHeight() / (float) image.getWidth(); + fHeight = Math.round(destinationHeight * sum); + } + // else sides are equal and is set to destination size at initialization of + } + + BufferedImage resizedImage = new BufferedImage(fWidth, fHeight, type); + Graphics2D g = resizedImage.createGraphics(); + g.setComposite(AlphaComposite.Src); + + g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + g.drawImage(image, 0, 0, fWidth, fHeight, null); + g.dispose(); + + return resizedImage; + } + + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/utils/ProductPriceUtils.java b/sm-core/src/main/java/com/salesmanager/core/business/utils/ProductPriceUtils.java new file mode 100755 index 0000000000..1ea3701f71 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/utils/ProductPriceUtils.java @@ -0,0 +1,722 @@ +package com.salesmanager.core.business.utils; + +import java.math.BigDecimal; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Currency; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Optional; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.apache.commons.validator.routines.BigDecimalValidator; +import org.apache.commons.validator.routines.CurrencyValidator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.orderproduct.OrderProduct; + +/** + * This class determines the price that is displayed in the catalogue for a + * given item. It does not calculate the total price for a given item + * + * @author casams1 + * + */ +@Component("priceUtil") +public class ProductPriceUtils { + + private final static char DECIMALCOUNT = '2'; + private final static char DECIMALPOINT = '.'; + private final static char THOUSANDPOINT = ','; + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductPriceUtils.class); + + /** + * Get the price without discount + * + * @param store + * @param product + * @param locale + * @return + */ + // Pricer + public BigDecimal getPrice(MerchantStore store, Product product, Locale locale) { + + BigDecimal defaultPrice = new BigDecimal(0); + + Set availabilities = product.getAvailabilities(); + for (ProductAvailability availability : availabilities) { + + Set prices = availability.getPrices(); + for (ProductPrice price : prices) { + + if (price.isDefaultPrice()) { + defaultPrice = price.getProductPriceAmount(); + } + } + } + + return defaultPrice; + } + + /** + * This method calculates the final price taking into account all attributes + * included having a specified default attribute with an attribute price gt 0 in + * the product object. The calculation is based on the default price. Attributes + * may be null + * + * @param Product + * @param List + * @return FinalPrice + */ + // Pricer + public FinalPrice getFinalPrice(Product product, List attributes) throws ServiceException { + + FinalPrice finalPrice = calculateFinalPrice(product); + + // attributes + BigDecimal attributePrice = null; + if (attributes != null && attributes.size() > 0) { + for (ProductAttribute attribute : attributes) { + if (attribute.getProductAttributePrice() != null + && attribute.getProductAttributePrice().doubleValue() > 0) { + if (attributePrice == null) { + attributePrice = new BigDecimal(0); + } + attributePrice = attributePrice.add(attribute.getProductAttributePrice()); + } + } + + if (attributePrice != null && attributePrice.doubleValue() > 0) { + BigDecimal fp = finalPrice.getFinalPrice(); + fp = fp.add(attributePrice); + finalPrice.setFinalPrice(fp); + + BigDecimal op = finalPrice.getOriginalPrice(); + op = op.add(attributePrice); + finalPrice.setOriginalPrice(op); + + BigDecimal dp = finalPrice.getDiscountedPrice(); + if (dp != null) { + dp = dp.add(attributePrice); + finalPrice.setDiscountedPrice(dp); + } + + } + } + + return finalPrice; + } + + /** + * This is the final price calculated from all configured prices and all + * possibles discounts. This price does not calculate the attributes or other + * prices than the default one + * + * @param store + * @param product + * @param locale + * @return + */ + // Pricer + public FinalPrice getFinalPrice(Product product) throws ServiceException { + + FinalPrice finalPrice = calculateFinalPrice(product); + + // attributes + BigDecimal attributePrice = null; + if (product.getAttributes() != null && product.getAttributes().size() > 0) { + for (ProductAttribute attribute : product.getAttributes()) { + if (attribute.getAttributeDefault()) { + if (attribute.getProductAttributePrice() != null + && attribute.getProductAttributePrice().doubleValue() > 0) { + if (attributePrice == null) { + attributePrice = new BigDecimal(0); + } + attributePrice = attributePrice.add(attribute.getProductAttributePrice()); + } + } + } + + if (attributePrice != null && attributePrice.doubleValue() > 0) { + BigDecimal fp = finalPrice.getFinalPrice(); + fp = fp.add(attributePrice); + finalPrice.setFinalPrice(fp); + + BigDecimal op = finalPrice.getOriginalPrice(); + op = op.add(attributePrice); + finalPrice.setOriginalPrice(op); + } + } + + finalPrice.setStringPrice(getStringAmount(finalPrice.getFinalPrice())); + if (finalPrice.isDiscounted()) { + finalPrice.setStringDiscountedPrice(getStringAmount(finalPrice.getDiscountedPrice())); + } + return finalPrice; + + } + + // Pricer + public FinalPrice getFinalPrice(ProductVariant variant) throws ServiceException { + + Validate.notNull(variant, "ProductVariant must not be null"); + Validate.notNull(variant.getProduct(), "variant.product must not be null"); + Validate.notNull(variant.getAuditSection(), "variant.availabilities must not be null or empty"); + + FinalPrice finalPrice = null; + List otherPrices = null; + + for (ProductAvailability availability : variant.getAvailabilities()) { + if (!StringUtils.isEmpty(availability.getRegion()) + && availability.getRegion().equals(Constants.ALL_REGIONS)) {// TODO REL 2.1 accept a region + Set prices = availability.getPrices(); + for (ProductPrice price : prices) { + + FinalPrice p = finalPrice(price); + if (price.isDefaultPrice()) { + finalPrice = p; + } else { + if (otherPrices == null) { + otherPrices = new ArrayList(); + } + otherPrices.add(p); + } + } + } + } + + if (finalPrice != null) { + finalPrice.setAdditionalPrices(otherPrices); + } else { + if (otherPrices != null) { + finalPrice = otherPrices.get(0); + } + } + + if (finalPrice == null) { + throw new ServiceException(ServiceException.EXCEPTION_ERROR, + "No inventory available to calculate the price. Availability should contain at least a region set to *"); + } + + return finalPrice; + + } + + public FinalPrice getFinalPrice(ProductAvailability availability) throws ServiceException { + + FinalPrice finalPrice = calculateFinalPrice(availability); + + if (finalPrice == null) { + throw new ServiceException(ServiceException.EXCEPTION_ERROR, + "No inventory available to calculate the price. Availability should contain at least a region set to *"); + } + + finalPrice.setStringPrice(getStringAmount(finalPrice.getFinalPrice())); + if (finalPrice.isDiscounted()) { + finalPrice.setStringDiscountedPrice(getStringAmount(finalPrice.getDiscountedPrice())); + } + return finalPrice; + + } + + /** + * This is the format that will be displayed in the admin input text fields when + * editing an entity having a BigDecimal to be displayed as a raw amount + * 1,299.99 The admin user will also be force to input the amount using that + * format + * + * @param store + * @param amount + * @return + * @throws Exception + */ + @Deprecated + public String getAdminFormatedAmount(MerchantStore store, BigDecimal amount) throws Exception { + + if (amount == null) { + return ""; + } + + NumberFormat nf = NumberFormat.getInstance(Constants.DEFAULT_LOCALE); + + nf.setMaximumFractionDigits(Integer.parseInt(Character.toString(DECIMALCOUNT))); + nf.setMinimumFractionDigits(Integer.parseInt(Character.toString(DECIMALCOUNT))); + + return nf.format(amount); + } + + // Utility + public String getStringAmount(BigDecimal amount) { + + if (amount == null) { + return ""; + } + + NumberFormat nf = NumberFormat.getInstance(Constants.DEFAULT_LOCALE); + + nf.setMaximumFractionDigits(Integer.parseInt(Character.toString(DECIMALCOUNT))); + nf.setMinimumFractionDigits(Integer.parseInt(Character.toString(DECIMALCOUNT))); + + return nf.format(amount); + } + + /** + * This method has to be used to format store front amounts It will display + * national format amount ex: $1,345.99 Rs.1.345.99 or international format + * USD1,345.79 INR1,345.79 + * + * @param store + * @param amount + * @return String + * @throws Exception + */ + // Utility + public String getStoreFormatedAmountWithCurrency(MerchantStore store, BigDecimal amount) throws Exception { + if (amount == null) { + return ""; + } + + Currency currency = Constants.DEFAULT_CURRENCY; + Locale locale = Constants.DEFAULT_LOCALE; + + try { + currency = store.getCurrency().getCurrency(); + locale = new Locale(store.getDefaultLanguage().getCode(), store.getCountry().getIsoCode()); + } catch (Exception e) { + LOGGER.error("Cannot create currency or locale instance for store " + store.getCode()); + } + + NumberFormat currencyInstance = null; + + if (store.isCurrencyFormatNational()) { + currencyInstance = NumberFormat.getCurrencyInstance(locale);// national + } else { + currencyInstance = NumberFormat.getCurrencyInstance();// international + } + currencyInstance.setCurrency(currency); + + return currencyInstance.format(amount.doubleValue()); + + } + + // Utility + public String getFormatedAmountWithCurrency(Locale locale, + com.salesmanager.core.model.reference.currency.Currency currency, BigDecimal amount) throws Exception { + if (amount == null) { + return ""; + } + + Currency curr = currency.getCurrency(); + NumberFormat currencyInstance = NumberFormat.getCurrencyInstance(locale); + currencyInstance.setCurrency(curr); + return currencyInstance.format(amount.doubleValue()); + + } + + /** + * This method will return the required formated amount with the appropriate + * currency + * + * @param store + * @param amount + * @return + * @throws Exception + */ + @Deprecated + public String getAdminFormatedAmountWithCurrency(MerchantStore store, BigDecimal amount) throws Exception { + if (amount == null) { + return ""; + } + + NumberFormat nf = null; + + Currency currency = store.getCurrency().getCurrency(); + nf = NumberFormat.getInstance(Constants.DEFAULT_LOCALE); + nf.setMaximumFractionDigits(Integer.parseInt(Character.toString(DECIMALCOUNT))); + nf.setMinimumFractionDigits(Integer.parseInt(Character.toString(DECIMALCOUNT))); + nf.setCurrency(currency); + + return nf.format(amount); + } + + /** + * Returns a formatted amount using Shopizer Currency requires internal + * java.util.Currency populated + * + * @param currency + * @param amount + * @return + * @throws Exception + */ + // Utility + public String getFormatedAmountWithCurrency(com.salesmanager.core.model.reference.currency.Currency currency, + BigDecimal amount) throws Exception { + if (amount == null) { + return ""; + } + + Validate.notNull(currency.getCurrency(), "Currency must be populated with java.util.Currency"); + NumberFormat nf = null; + + Currency curr = currency.getCurrency(); + nf = NumberFormat.getInstance(Constants.DEFAULT_LOCALE); + nf.setMaximumFractionDigits(Integer.parseInt(Character.toString(DECIMALCOUNT))); + nf.setMinimumFractionDigits(Integer.parseInt(Character.toString(DECIMALCOUNT))); + nf.setCurrency(curr); + + return nf.format(amount); + } + + /** + * This amount will be displayed to the end user + * + * @param store + * @param amount + * @param locale + * @return + * @throws Exception + */ + // Utility + public String getFormatedAmountWithCurrency(MerchantStore store, BigDecimal amount, Locale locale) + throws Exception { + + NumberFormat nf = null; + + Currency currency = store.getCurrency().getCurrency(); + + nf = NumberFormat.getInstance(locale); + nf.setCurrency(currency); + nf.setMaximumFractionDigits(Integer.parseInt(Character.toString(DECIMALCOUNT))); + nf.setMinimumFractionDigits(Integer.parseInt(Character.toString(DECIMALCOUNT))); + + return nf.format(amount); + + } + + /** + * Transformation of an amount of money submited by the admin user to be + * inserted as a BigDecimal in the database + * + * @param amount + * @param locale + * @return + * @throws Exception + */ + // Utility + public BigDecimal getAmount(String amount) throws Exception { + + // validations + /** + * 1) remove decimal and thousand + * + * String.replaceAll(decimalPoint, ""); String.replaceAll(thousandPoint, ""); + * + * Should be able to parse to Integer + */ + StringBuilder newAmount = new StringBuilder(); + for (int i = 0; i < amount.length(); i++) { + if (amount.charAt(i) != DECIMALPOINT && amount.charAt(i) != THOUSANDPOINT) { + newAmount.append(amount.charAt(i)); + } + } + + try { + Integer.parseInt(newAmount.toString()); + } catch (Exception e) { + throw new Exception("Cannot parse " + amount); + } + + if (!amount.contains(Character.toString(DECIMALPOINT)) && !amount.contains(Character.toString(THOUSANDPOINT)) + && !amount.contains(" ")) { + + if (matchPositiveInteger(amount)) { + BigDecimalValidator validator = CurrencyValidator.getInstance(); + BigDecimal bdamount = validator.validate(amount, Locale.US); + if (bdamount == null) { + throw new Exception("Cannot parse " + amount); + } else { + return bdamount; + } + } else { + throw new Exception("Not a positive integer " + amount); + } + + } else { + // TODO should not go this path in this current release + StringBuilder pat = new StringBuilder(); + + if (!StringUtils.isBlank(Character.toString(THOUSANDPOINT))) { + pat.append("\\d{1,3}(" + THOUSANDPOINT + "?\\d{3})*"); + } + + pat.append("(\\" + DECIMALPOINT + "\\d{1," + DECIMALCOUNT + "})"); + + Pattern pattern = Pattern.compile(pat.toString()); + Matcher matcher = pattern.matcher(amount); + + if (matcher.matches()) { + + Locale locale = Constants.DEFAULT_LOCALE; + // TODO validate amount using old test case + if (DECIMALPOINT == ',') { + locale = Locale.GERMAN; + } + + BigDecimalValidator validator = CurrencyValidator.getInstance(); + + return validator.validate(amount, locale); + } else { + throw new Exception("Cannot parse " + amount); + } + } + + } + + // Move to OrderTotalService + public BigDecimal getOrderProductTotalPrice(MerchantStore store, OrderProduct orderProduct) { + + BigDecimal finalPrice = orderProduct.getOneTimeCharge(); + finalPrice = finalPrice.multiply(new BigDecimal(orderProduct.getProductQuantity())); + return finalPrice; + } + + /** + * Determines if a ProductPrice has a discount + * + * @param productPrice + * @return + */ + // discounter + public boolean hasDiscount(ProductPrice productPrice) { + + Date today = new Date(); + + // calculate discount price + boolean hasDiscount = false; + if (productPrice.getProductPriceSpecialStartDate() != null + || productPrice.getProductPriceSpecialEndDate() != null) { + + if (productPrice.getProductPriceSpecialStartDate() != null) { + if (productPrice.getProductPriceSpecialStartDate().before(today)) { + if (productPrice.getProductPriceSpecialEndDate() != null) { + if (productPrice.getProductPriceSpecialEndDate().after(today)) { + hasDiscount = true; + } + } + } + } + } + + return hasDiscount; + } + + private boolean matchPositiveInteger(String amount) { + Pattern pattern = Pattern.compile("^[+]?\\d*$"); + Matcher matcher = pattern.matcher(amount); + return matcher.matches(); + } + + private Set applicableAvailabilities(Set availabilities) + throws ServiceException { + if (CollectionUtils.isEmpty(availabilities)) { + throw new ServiceException(ServiceException.EXCEPTION_ERROR, + "No applicable inventory to calculate the price."); + } + + return new HashSet(availabilities.stream() + .filter(a -> !CollectionUtils.isEmpty(a.getPrices())).collect(Collectors.toList())); + } + + private FinalPrice calculateFinalPrice(Product product) throws ServiceException { + + FinalPrice finalPrice = null; + List otherPrices = null; + + /** + * Since 3.2.0 The rule is + * + * If product.variants contains exactly one variant If Variant has availability + * we use availability from variant Otherwise we use price + */ + + Set availabilities = null; + if (!CollectionUtils.isEmpty(product.getVariants())) { + Optional variants = product.getVariants().stream().filter(i -> i.isDefaultSelection()) + .findFirst(); + if (variants.isPresent()) { + availabilities = variants.get().getAvailabilities(); + availabilities = this.applicableAvailabilities(availabilities); + + } + } + + if (CollectionUtils.isEmpty(availabilities)) { + availabilities = product.getAvailabilities(); + availabilities = this.applicableAvailabilities(availabilities); + } + + for (ProductAvailability availability : availabilities) { + if (!StringUtils.isEmpty(availability.getRegion()) + && availability.getRegion().equals(Constants.ALL_REGIONS)) {// TODO REL 2.1 accept a region + Set prices = availability.getPrices(); + for (ProductPrice price : prices) { + + FinalPrice p = finalPrice(price); + if (price.isDefaultPrice()) { + finalPrice = p; + } else { + if (otherPrices == null) { + otherPrices = new ArrayList(); + } + otherPrices.add(p); + } + } + } + } + + if (finalPrice != null) { + finalPrice.setAdditionalPrices(otherPrices); + } else { + if (otherPrices != null) { + finalPrice = otherPrices.get(0); + } + } + + if (finalPrice == null) { + throw new ServiceException(ServiceException.EXCEPTION_ERROR, + "No inventory available to calculate the price. Availability should contain at least a region set to *"); + } + + return finalPrice; + + } + + private FinalPrice calculateFinalPrice(ProductAvailability availability) throws ServiceException { + + FinalPrice finalPrice = null; + List otherPrices = null; + + Set prices = availability.getPrices(); + for (ProductPrice price : prices) { + + FinalPrice p = finalPrice(price); + if (price.isDefaultPrice()) { + finalPrice = p; + } else { + if (otherPrices == null) { + otherPrices = new ArrayList(); + } + otherPrices.add(p); + } + + } + + if (finalPrice != null) { + finalPrice.setAdditionalPrices(otherPrices); + } else { + if (otherPrices != null) { + finalPrice = otherPrices.get(0); + } + } + + if (finalPrice == null) { + throw new ServiceException(ServiceException.EXCEPTION_ERROR, + "No inventory available to calculate the price. Availability should contain at least a region set to *"); + } + + return finalPrice; + + } + + private FinalPrice finalPrice(ProductPrice price) { + + FinalPrice finalPrice = new FinalPrice(); + BigDecimal fPrice = price.getProductPriceAmount(); + BigDecimal oPrice = price.getProductPriceAmount(); + + Date today = new Date(); + // calculate discount price + boolean hasDiscount = false; + if (price.getProductPriceSpecialStartDate() != null || price.getProductPriceSpecialEndDate() != null) { + + if (price.getProductPriceSpecialStartDate() != null) { + if (price.getProductPriceSpecialStartDate().before(today)) { + if (price.getProductPriceSpecialEndDate() != null) { + if (price.getProductPriceSpecialEndDate().after(today)) { + hasDiscount = true; + fPrice = price.getProductPriceSpecialAmount(); + finalPrice.setDiscountEndDate(price.getProductPriceSpecialEndDate()); + } + } + + } + } + + if (!hasDiscount && price.getProductPriceSpecialStartDate() == null + && price.getProductPriceSpecialEndDate() != null) { + if (price.getProductPriceSpecialEndDate().after(today)) { + hasDiscount = true; + fPrice = price.getProductPriceSpecialAmount(); + finalPrice.setDiscountEndDate(price.getProductPriceSpecialEndDate()); + } + } + } else { + if (price.getProductPriceSpecialAmount() != null + && price.getProductPriceSpecialAmount().doubleValue() > 0) { + hasDiscount = true; + fPrice = price.getProductPriceSpecialAmount(); + finalPrice.setDiscountEndDate(price.getProductPriceSpecialEndDate()); + } + } + + finalPrice.setProductPrice(price); + finalPrice.setFinalPrice(fPrice); + finalPrice.setOriginalPrice(oPrice); + + if (price.isDefaultPrice()) { + finalPrice.setDefaultPrice(true); + } + if (hasDiscount) { + discountPrice(finalPrice); + } + + return finalPrice; + } + + private void discountPrice(FinalPrice finalPrice) { + + finalPrice.setDiscounted(true); + + double arith = finalPrice.getProductPrice().getProductPriceSpecialAmount().doubleValue() + / finalPrice.getProductPrice().getProductPriceAmount().doubleValue(); + double fsdiscount = 100 - (arith * 100); + Float percentagediscount = new Float(fsdiscount); + int percent = percentagediscount.intValue(); + finalPrice.setDiscountPercent(percent); + + // calculate percent + BigDecimal price = finalPrice.getOriginalPrice(); + finalPrice.setDiscountedPrice(finalPrice.getProductPrice().getProductPriceSpecialAmount()); + } + +} \ No newline at end of file diff --git a/sm-core/src/main/java/com/salesmanager/core/business/utils/ProductUtils.java b/sm-core/src/main/java/com/salesmanager/core/business/utils/ProductUtils.java new file mode 100755 index 0000000000..a4f592a3e3 --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/utils/ProductUtils.java @@ -0,0 +1,42 @@ +package com.salesmanager.core.business.utils; + +import java.util.Set; + +import com.salesmanager.core.model.order.orderproduct.OrderProduct; +import com.salesmanager.core.model.order.orderproduct.OrderProductAttribute; + +public class ProductUtils { + + public static String buildOrderProductDisplayName(OrderProduct orderProduct) { + + String pName = orderProduct.getProductName(); + Set oAttributes = orderProduct.getOrderAttributes(); + StringBuilder attributeName = null; + for(OrderProductAttribute oProductAttribute : oAttributes) { + if(attributeName == null) { + attributeName = new StringBuilder(); + attributeName.append("["); + } else { + attributeName.append(", "); + } + attributeName.append(oProductAttribute.getProductAttributeName()) + .append(": ") + .append(oProductAttribute.getProductAttributeValueName()); + + } + + + StringBuilder productName = new StringBuilder(); + productName.append(pName); + + if(attributeName!=null) { + attributeName.append("]"); + productName.append(" ").append(attributeName.toString()); + } + + return productName.toString(); + + + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/utils/RepositoryHelper.java b/sm-core/src/main/java/com/salesmanager/core/business/utils/RepositoryHelper.java new file mode 100644 index 0000000000..b71b1fafbd --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/utils/RepositoryHelper.java @@ -0,0 +1,42 @@ +package com.salesmanager.core.business.utils; + +import javax.persistence.Query; + +import com.salesmanager.core.model.common.Criteria; +import com.salesmanager.core.model.common.GenericEntityList; + +/** + * Helper for Spring Data JPA + * + * @author carlsamson + * + */ +public class RepositoryHelper { + + @SuppressWarnings("rawtypes") + public static Query paginateQuery(Query q, Number count, GenericEntityList entityList, Criteria criteria) { + + if (entityList == null) { + entityList = new GenericEntityList(); + } + + if (criteria.isLegacyPagination()) { + if (criteria.getMaxCount() > 0) { + q.setFirstResult(criteria.getStartIndex()); + q.setMaxResults(Math.min(criteria.getMaxCount(), count.intValue())); + } + } else { + //int firstResult = ((criteria.getStartPage()==0?criteria.getStartPage()+1:criteria.getStartPage()) - 1) * criteria.getPageSize(); + int firstResult = ((criteria.getStartPage()==0?0:criteria.getStartPage())) * criteria.getPageSize(); + q.setFirstResult(firstResult); + q.setMaxResults(criteria.getPageSize()); + int lastPageNumber = (count.intValue() / criteria.getPageSize()) + 1; + entityList.setTotalPages(lastPageNumber); + entityList.setTotalCount(count.intValue()); + } + + return q; + + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/utils/SecurityGroupsBuilder.java b/sm-core/src/main/java/com/salesmanager/core/business/utils/SecurityGroupsBuilder.java new file mode 100644 index 0000000000..1b585a26ba --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/utils/SecurityGroupsBuilder.java @@ -0,0 +1,74 @@ +package com.salesmanager.core.business.utils; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.model.user.GroupType; +import com.salesmanager.core.model.user.Permission; + +/** + * Helper for building security groups and permissions + * @author carlsamson + * + */ +public class SecurityGroupsBuilder { + + private List groups = new ArrayList(); + private Group lastGroup = null; + + + public SecurityGroupsBuilder addGroup(String name, GroupType type) { + + Group g = new Group(); + g.setGroupName(name); + g.setGroupType(type); + groups.add(g); + this.lastGroup = g; + + return this; + } + + public SecurityGroupsBuilder addPermission(String name) { + if(this.lastGroup == null) { + Group g = this.groups.get(0); + if(g == null) { + g = new Group(); + g.setGroupName("UNDEFINED"); + g.setGroupType(GroupType.ADMIN); + groups.add(g); + this.lastGroup = g; + } + } + + Permission permission = new Permission(); + permission.setPermissionName(name); + lastGroup.getPermissions().add(permission); + + return this; + } + + public SecurityGroupsBuilder addPermission(Permission permission) { + + if(this.lastGroup == null) { + Group g = this.groups.get(0); + if(g == null) { + g = new Group(); + g.setGroupName("UNDEFINED"); + g.setGroupType(GroupType.ADMIN); + groups.add(g); + this.lastGroup = g; + } + } + + + lastGroup.getPermissions().add(permission); + + return this; + } + + public List build() { + return groups; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/utils/ajax/AjaxPageableResponse.java b/sm-core/src/main/java/com/salesmanager/core/business/utils/ajax/AjaxPageableResponse.java new file mode 100755 index 0000000000..8b07222e9b --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/utils/ajax/AjaxPageableResponse.java @@ -0,0 +1,108 @@ +package com.salesmanager.core.business.utils.ajax; + +import java.util.Map; +import java.util.Set; + +import org.json.simple.JSONObject; + +public class AjaxPageableResponse extends AjaxResponse { + + + private int startRow; + public int getStartRow() { + return startRow; + } + + + + public void setStartRow(int startRow) { + this.startRow = startRow; + } + + + + private int endRow; + private int totalRow; + + protected String getPageInfo() { + + StringBuilder returnString = new StringBuilder(); + returnString.append("\"startRow\"").append(":"); + returnString.append(this.startRow).append(","); + returnString.append("\"endRow\"").append(":").append(this.endRow).append(","); + returnString.append("\"totalRows\"").append(":").append(super.getData().size()); + return returnString.toString(); + + } + + + + @SuppressWarnings("unchecked") + @Override + public String toJSONString() { + + StringBuilder returnString = new StringBuilder(); + + returnString.append(getJsonInfo()).append(","); + returnString.append(getPageInfo()); + + if(this.getData().size()>0) { + StringBuilder dataEntries = null; + int count = 0; + for(Map keyValue : this.getData()) { + if(dataEntries == null) { + dataEntries = new StringBuilder(); + } + JSONObject data = new JSONObject(); + Set keys = keyValue.keySet(); + for(String key : keys) { + data.put(key, keyValue.get(key)); + } + String dataField = data.toJSONString(); + dataEntries.append(dataField); + if(count> data = new ArrayList<>(); + private Map dataMap = new HashMap<>(); + private Map validationMessages = new HashMap<>(); + public Map getValidationMessages() { + return validationMessages; + } + public void setValidationMessages(Map validationMessages) { + this.validationMessages = validationMessages; + } + public int getStatus() { + return status; + } + public void setStatus(int status) { + this.status = status; + } + protected List> getData() { + return data; + } + + public void addDataEntry(Map dataEntry) { + this.data.add(dataEntry); + } + + public void addEntry(String key, String value) { + dataMap.put(key, value); + } + + + public void setErrorMessage(Throwable t) { + this.setStatusMessage(t.getMessage()); + } + + public void setErrorString(String t) { + this.setStatusMessage(t); + } + + + public void addValidationMessage(String fieldName, String message) { + this.validationMessages.put(fieldName, message); + } + + private String statusMessage = null; + + + public String getStatusMessage() { + return statusMessage; + } + public void setStatusMessage(String statusMessage) { + this.statusMessage = statusMessage; + } + + + protected String getJsonInfo() { + + StringBuilder returnString = new StringBuilder(); + returnString.append("{"); + returnString.append("\"response\"").append(":"); + returnString.append("{"); + returnString.append("\"status\"").append(":").append(this.getStatus()); + if(this.getStatusMessage()!=null && this.getStatus()!=0) { + returnString.append(",").append("\"statusMessage\"").append(":\"").append(JSONObject.escape(this.getStatusMessage())).append("\""); + } + return returnString.toString(); + + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public String toJSONString() { + StringBuilder returnString = new StringBuilder(); + + returnString.append(getJsonInfo()); + + if(this.getData().size()>0) { + StringBuilder dataEntries = null; + int count = 0; + for(Map keyValue : this.getData()) { + if(dataEntries == null) { + dataEntries = new StringBuilder(); + } + JSONObject data = new JSONObject(); + Set keys = keyValue.keySet(); + for(String key : keys) { + data.put(key, keyValue.get(key)); + } + String dataField = data.toJSONString(); + dataEntries.append(dataField); + if(count0) { + StringBuilder dataEntries = null; + int count = 0; + for(String key : this.getDataMap().keySet()) { + if(dataEntries == null) { + dataEntries = new StringBuilder(); + } + + dataEntries.append("\"").append(key).append("\""); + dataEntries.append(":"); + dataEntries.append("\"").append(this.getDataMap().get(key)).append("\""); + + if(count getDataMap() { + return dataMap; + } + public void setDataMap(Map dataMap) { + this.dataMap = dataMap; + } + +} diff --git a/sm-core/src/main/java/com/salesmanager/core/business/utils/query/ProductQueryBuilder.java b/sm-core/src/main/java/com/salesmanager/core/business/utils/query/ProductQueryBuilder.java new file mode 100755 index 0000000000..dc139e091a --- /dev/null +++ b/sm-core/src/main/java/com/salesmanager/core/business/utils/query/ProductQueryBuilder.java @@ -0,0 +1,67 @@ +package com.salesmanager.core.business.utils.query; + +public class ProductQueryBuilder { + + public static String buildProductQuery() { + + StringBuilder qs = new StringBuilder(); + + //option 1 + qs.append("select distinct p from Product as p "); + qs.append("join fetch p.availabilities pa "); + qs.append("join fetch p.descriptions pd "); + qs.append("join fetch p.merchantStore pm "); + qs.append("left join fetch pa.prices pap "); + qs.append("left join fetch pap.descriptions papd "); + + + //images + qs.append("left join fetch p.images images "); + //options + qs.append("left join fetch p.attributes pattr "); + qs.append("left join fetch pattr.productOption po "); + qs.append("left join fetch po.descriptions pod "); + qs.append("left join fetch pattr.productOptionValue pov "); + qs.append("left join fetch pov.descriptions povd "); + qs.append("left join fetch p.relationships pr ");//no relationships + //other lefts + qs.append("left join fetch p.manufacturer manuf "); + qs.append("left join fetch manuf.descriptions manufd "); + qs.append("left join fetch p.type type "); + qs.append("left join fetch p.taxClass tx "); + + + + //option 2 no relationships + + qs.append("select distinct p from Product as p "); + qs.append("join fetch p.merchantStore merch "); + qs.append("join fetch p.availabilities pa "); + qs.append("left join fetch pa.prices pap "); + + qs.append("join fetch p.descriptions pd "); + qs.append("join fetch p.categories categs "); + + qs.append("left join fetch pap.descriptions papd "); + + + //images + qs.append("left join fetch p.images images "); + + //options (do not need attributes for listings) + qs.append("left join fetch p.attributes pattr "); + qs.append("left join fetch pattr.productOption po "); + qs.append("left join fetch po.descriptions pod "); + qs.append("left join fetch pattr.productOptionValue pov "); + qs.append("left join fetch pov.descriptions povd "); + + //other lefts + qs.append("left join fetch p.manufacturer manuf "); + qs.append("left join fetch manuf.descriptions manufd "); + qs.append("left join fetch p.type type "); + qs.append("left join fetch p.taxClass tx "); + + return qs.toString(); + } + +} diff --git a/sm-core/src/main/resources/authentication.properties b/sm-core/src/main/resources/authentication.properties new file mode 100755 index 0000000000..1c68107b48 --- /dev/null +++ b/sm-core/src/main/resources/authentication.properties @@ -0,0 +1,21 @@ + +authToken.header=Authorization + +#JWT authentication configuration for sm-shop +jwt.header=Authorization +jwt.secret=aSecret +jwt.expiration= 604800 + + +#Your facebook app informations +facebook.app.id= +facebook.app.secret= +facebook.app.access_token= + + + + + + + + diff --git a/sm-core/src/main/resources/com/salesmanager/drools/rules/PriceByDistance.drl b/sm-core/src/main/resources/com/salesmanager/drools/rules/PriceByDistance.drl new file mode 100644 index 0000000000..ba7fe3efc2 --- /dev/null +++ b/sm-core/src/main/resources/com/salesmanager/drools/rules/PriceByDistance.drl @@ -0,0 +1,21 @@ +package com.salesmanager.drools.rules; + +import com.salesmanager.core.business.modules.integration.shipping.impl.ShippingInputParameters; + +global com.salesmanager.core.business.modules.integration.shipping.impl.DecisionResponse decision; + +dialect "mvel" + +rule "530 kilometers or less" + when + ShippingInputParameters(distance <= 530) + then + decision.setCustomPrice("75"); +end + +rule "3550 kilometers or less" + when + ShippingInputParameters(distance <=3550) + then + decision.setCustomPrice("140"); +end diff --git a/sm-core/src/main/resources/com/salesmanager/drools/rules/PriceByDistance2.drl b/sm-core/src/main/resources/com/salesmanager/drools/rules/PriceByDistance2.drl new file mode 100644 index 0000000000..e1bc6518b8 --- /dev/null +++ b/sm-core/src/main/resources/com/salesmanager/drools/rules/PriceByDistance2.drl @@ -0,0 +1,28 @@ +package com.salesmanager.drools.rules; + +import com.salesmanager.core.business.modules.integration.shipping.impl.ShippingInputParameters; + +global com.salesmanager.core.business.modules.integration.shipping.impl.DecisionResponse decision; + +dialect "mvel" + +rule "40 kilometers or less" + when + ShippingInputParameters(distance <= 40) + then + decision.setCustomPrice("75"); +end + +rule "80 kilometers or less" + when + ShippingInputParameters(distance > 40 && distance <=80) + then + decision.setCustomPrice("120"); +end + +rule "2550 kilometers or less" + when + ShippingInputParameters(distance > 80 && distance <=2550) + then + decision.setCustomPrice("140"); +end diff --git a/sm-core/src/main/resources/com/salesmanager/drools/rules/PromoCoupon.drl b/sm-core/src/main/resources/com/salesmanager/drools/rules/PromoCoupon.drl new file mode 100644 index 0000000000..8883e61aba --- /dev/null +++ b/sm-core/src/main/resources/com/salesmanager/drools/rules/PromoCoupon.drl @@ -0,0 +1,16 @@ +package com.salesmanager.drools.rules; + +import com.salesmanager.core.business.modules.order.total.OrderTotalInputParameters; + +global com.salesmanager.core.business.modules.order.total.OrderTotalResponse total; + +dialect "mvel" + + +rule "Bam0520" + when + OrderTotalInputParameters(promoCode == 'Test1234') + OrderTotalInputParameters(date < "31-Oct-2025") + then + total.setDiscount(0.10); +end diff --git a/sm-core/src/main/resources/com/salesmanager/drools/rules/ShippingDecision.drl b/sm-core/src/main/resources/com/salesmanager/drools/rules/ShippingDecision.drl new file mode 100644 index 0000000000..f70c071b3a --- /dev/null +++ b/sm-core/src/main/resources/com/salesmanager/drools/rules/ShippingDecision.drl @@ -0,0 +1,25 @@ +package com.salesmanager.drools.rules; + +import com.salesmanager.core.business.modules.integration.shipping.impl.ShippingInputParameters; + +global com.salesmanager.core.business.modules.integration.shipping.impl.DecisionResponse decision; + +dialect "mvel" + +rule "Shipping decision Canada Post" + when + ShippingInputParameters(weight < 62) + ShippingInputParameters(size < 66) + ShippingInputParameters(country == "CA") + then + decision.setModuleName("canadapost"); +end + +rule "Shipping decision Home Delivery" + when + ShippingInputParameters(weight > 62 || size > 66) + ShippingInputParameters(country == "CA") + ShippingInputParameters(province == "QC") + then + decision.setModuleName("priceByDistance"); +end diff --git a/sm-core/src/main/resources/email.properties b/sm-core/src/main/resources/email.properties new file mode 100755 index 0000000000..4bedfaf845 --- /dev/null +++ b/sm-core/src/main/resources/email.properties @@ -0,0 +1,9 @@ +#GMail sample configuration +#May require a keystore for certificates +mailSender.protocol=smtps +mailSender.host=smtp.gmail.com +mailSender.port=465 +mailSender.username=youremail@gmail.com +mailSender.password=yourpassword +mailSender.mail.smtp.auth=true +mail.smtp.starttls.enable=true \ No newline at end of file diff --git a/sm-core/src/main/resources/profiles/aws/shopizer-core.properties b/sm-core/src/main/resources/profiles/aws/shopizer-core.properties new file mode 100755 index 0000000000..fd8c8e8281 --- /dev/null +++ b/sm-core/src/main/resources/profiles/aws/shopizer-core.properties @@ -0,0 +1,67 @@ +#Must be 16 digits (replace with your own creation !) +secretKey=7070200000000007 + + +#Elastic Search configurations +elasticsearch.cluster.name=shopizer +elasticsearch.mode=remote +elasticsearch.server.host=localhost +elasticsearch.server.port=9200 +elasticsearch.server.proxy.user= +elasticsearch.server.proxy.password= +elasticsearch.security.enabled=false +elasticsearch.security.user=elastic +elasticsearch.security.password=changeme + +# Which CMS method to use +# default = infinispan +# httpd = requires http server +# aws = AWS S3 -> See AWS S3 configuration below + +config.cms.method=aws +config.cms.static.path=/static + +#Infinispan configuration +#Specifies where files are located +config.cms.store.location=./files/store +config.cms.files.location=./files/repos + +#httpd configuration +#Specifies where htdocs repository is located +config.cms.http.path.location= + +#AWS S3 configuration +#Name of bucket files +#See regions here https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html +#Credentials must be set as environment variables when launching Shopizer +#AWS_ACCESS_KEY_ID= +#AWS_SECRETE_ACCESS_KEY= +#config.cms.contentUrl=https://s3.ca-central-1.amazonaws.com/shopizer-lightsail +#config.cms.aws.bucket=shopizer-lightsail +#config.cms.aws.region=ca-central-1 + +config.cms.gcp.bucket= + +config.emailSender=default +config.emailSender.region=us_east_1 + +#Shipping activated in the system ? +config.displayShipping=true + +#Google map API key +#For using priceByDistance shipping module +shippingDistancePreProcessor.apiKey= + + +#checkout and signup address validation +#see : https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete-addressform +#Should be passed as an environment key +config.googleMapsKey= + +#recaptcha https://developers.google.com/recaptcha/ +config.recaptcha.secretkey= +config.recaptcha.siteKey= + +#shipping rules +config.shipping.rule.priceByDistance=PriceByDistance.drl +config.shipping.rule.shippingModuleDecision=ShippingDecision.drl \ No newline at end of file diff --git a/sm-core/src/main/resources/profiles/cloud/shopizer-core.properties b/sm-core/src/main/resources/profiles/cloud/shopizer-core.properties new file mode 100755 index 0000000000..64f8e8f9ff --- /dev/null +++ b/sm-core/src/main/resources/profiles/cloud/shopizer-core.properties @@ -0,0 +1,136 @@ +#Used in docker / docker compose + +#Must be 16 digits (replace with your own creation !) +secretKey=7070200000000007 + +# commented out properties need to be set from an environment variable +# when using this profile when running docker based application +# +# example of environment variables when running docker image using aws + +# See this git project for more examples https://github.com/shopizer-ecommerce/shopizer-docker-compose +# +# docker run -d -p 80:8080 shopizerecomm/shopizer:latest \ +# -e SPRING_PROFILES_ACTIVE=cloud \ +# -e JAVA_OPTS=-Xms1024m -Xmx1024m \ +# -e elasticsearch.server.host=x.x.x.x \ +# -e elasticsearch.server.port=9200 \ +# -e elasticsearch.server.protocole=http \ +# -e db.jdbcUrl=jdbc:mysql://x.x.x.x:3306/SALESMANAGER?autoReconnect=true&serverTimeZone=UTC&useUnicode=true&characterEncoding=UTF-8 \ +# -e db.user=shopizer_database_user \ +# -e db.password=shopizer_database_password \ +# -e config.cms.method=aws \ +# -e config.cms.contentUrl=https://s3.ca-central-1.amazonaws.com/bucketname \ +# -e GOOGLE_APPLICATION_CREDENTIALS=NO \ +# -e AWS_ACCESS_KEY_ID=YOUR-ACCESS-KEY \ +# -e AWS_SECRET_ACCESS_KEY=YOUR-SECRET-ACCESS-KEY \ +# -e config.cms.gcp.bucket=NO \ +# -e config.cms.aws.bucket=bucketname \ +# -e config.cms.aws.region=ca-central-1 \ +# -e elasticsearch.security.password=NO \ +# -e config.displayShipping=true \ +# -e config.googleMapsKey=GOOGLE-MAPS-KEY \ +# -e config.recaptcha.secretKey=RECAPTCHA-KEY \ +# -e config.recaptcha.siteKey=RECAPTCHA-SITE-KEY \ +# -e config.shippingDistancePreProcessor.acceptedZones=QC,ON,NB,XX,YY \ +# -e config.shippingDistancePreProcessor.apiKey=GOOGLE-MAPS-KEY \ +# -e config.emailSender=smtp \ +# -e config.emailSender.region=US_EAST_1 \ + + +#Deprecated in favor of search starter +#Elastic Search configurations +elasticsearch.cluster.name=shopizer +elasticsearch.mode=remote +#elasticsearch.server.host=localhost +elasticsearch.server.protocole=http +elasticsearch.server.port=9200 +elasticsearch.server.proxy.user= +elasticsearch.server.proxy.password= +elasticsearch.security.enabled=false +elasticsearch.security.user=elastic + +###Search starter configuration instead of config above +search.credentials.username=admin +search.credentials.password=admin + +search.clusterName=opensearch-cluster +#search.jksAbsolutePath=/Users/csa/Documents/dev/processes/open-search/config/testnode.jks +search.jksAbsolutePath= + +#Languages to be configured for the search engine. Too much will impact the size and how indexes are built +search.searchLanguages=en,fr + +search.host[0].scheme=http +search.host[0].host=localhost +search.host[0].port=9200 +#search.host[1].scheme=http +#search.host[1].host=host-2 +#search.host[1].port=9200 + + +# Which CMS method to use +# default = infinispan +# httpd = requires http server +# aws = AWS S3 -> See AWS S3 configuration below +# gcp + +#config.cms.method=aws +config.cms.static.path=/static + + +#Infinispan configuration +#Specifies where files are located +config.cms.store.location=./files/store +config.cms.files.location=./files/repos + +#httpd configuration +#Specifies where htdocs repository is located +config.cms.http.path.location= + +#AWS S3 configuration +#Name of bucket files +#See regions here https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html +#Credentials must be set as environment variables when launching Shopizer +#AWS_ACCESS_KEY_ID= +#AWS_SECRETE_ACCESS_KEY= +#config.cms.contentUrl=https://s3.ca-central-1.amazonaws.com/shopizer-lightsail +#config.cms.aws.bucket=shopizer-lightsail +#config.cms.aws.region=ca-central-1 + +#config.cms.gcp.bucket= + +#You need an AWS access key ID and AWS secret access key to access Amazon SES using an SDK +#AWS keys need to be specified in environment variables, see above +#default is using smtp and requires configurations from admin console +#Email implementation [default | ses] +#config.emailSender=ses +#config.emailSender.region=US_EAST_1 + +#Shipping activated in the system ? +config.displayShipping=true + +#Shipping activated in the system ? +config.displayShipping=true + + +#Google map API key +#For using priceByDistance shipping module +#config.shippingDistancePreProcessor.apiKey= +config.shippingDistancePreProcessor.acceptedZones=QC,ON,AB,NY,MA,NL,NS,NB,PE + +#checkout and signup address validation +#see : https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete-addressform +#Should be passed as an environment key + +#config.googleMapsKey= + +#recaptcha https://developers.google.com/recaptcha/ +#config.recaptcha.secretKey= +#config.recaptcha.siteKey= + + +#shipping rules +#config.shipping.rule.priceByDistance=PriceByDistance.drl +#config.shipping.rule.shippingModuleDecision=ShippingDecision.drl + diff --git a/sm-core/src/main/resources/profiles/dependency/shopizer-core.properties b/sm-core/src/main/resources/profiles/dependency/shopizer-core.properties new file mode 100644 index 0000000000..2e0c8eb97f --- /dev/null +++ b/sm-core/src/main/resources/profiles/dependency/shopizer-core.properties @@ -0,0 +1,79 @@ +#Must be 16 digits (replace with your own creation !) +secretKey=7070200000000007 + +# commented out properties need to be set from an environment variable +# when using this profile when running docker based application +# +# example of environment variables when running docker image using aws +# + +#Elastic Search configurations +elasticsearch.cluster.name=shopizer +elasticsearch.mode=remote +#elasticsearch.server.host=localhost +#elasticsearch.server.protocole=http +#elasticsearch.server.port=9200 +elasticsearch.server.proxy.user= +elasticsearch.server.proxy.password= +#elasticsearch.security.enabled=false +#elasticsearch.security.user=elastic + +# Which CMS method to use +# default = infinispan +# httpd = requires http server +# aws = AWS S3 -> See AWS S3 configuration below +# gcp + +config.cms.method=default +config.cms.static.path=/static + + +#Infinispan configuration +#Specifies where files are located +config.cms.store.location=./files/store +config.cms.files.location=./files/repos + +#httpd configuration +#Specifies where htdocs repository is located +config.cms.http.path.location= + +#AWS S3 configuration +#Name of bucket files +#See regions here https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html +#Credentials must be set as environment variables when launching Shopizer +#AWS_ACCESS_KEY_ID= +#AWS_SECRETE_ACCESS_KEY= +#config.cms.contentUrl=https://s3.ca-central-1.amazonaws.com/shopizer-lightsail +#config.cms.aws.bucket=shopizer-lightsail +#config.cms.aws.region=ca-central-1 + +#config.cms.gcp.bucket= + +#You need an AWS access key ID and AWS secret access key to access Amazon SES using an SDK +#AWS keys need to be specified in environment variables, see above +#default is using smtp and requires configurations from admin console +#Email implementation [default | ses] +config.emailSender=default +#config.emailSender.region=US_EAST_1 + +#Shipping activated in the system ? +config.displayShipping=true + + +#Google map API key +#For using priceByDistance shipping module +#config.shippingDistancePreProcessor.apiKey= +config.shippingDistancePreProcessor.acceptedZones=QC,ON,AB,NY,MA + +#checkout and signup address validation +#see : https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete-addressform +#Should be passed as an environment key +#config.googleMapsKey= + +#recaptcha https://developers.google.com/recaptcha/ +#config.recaptcha.secretKey= +#config.recaptcha.siteKey= + +#shipping rules +config.shipping.rule.priceByDistance=PriceByDistance.drl +config.shipping.rule.shippingModuleDecision=ShippingDecision.drl \ No newline at end of file diff --git a/sm-core/src/main/resources/profiles/gcp/shopizer-core.properties b/sm-core/src/main/resources/profiles/gcp/shopizer-core.properties new file mode 100755 index 0000000000..474f0e73b9 --- /dev/null +++ b/sm-core/src/main/resources/profiles/gcp/shopizer-core.properties @@ -0,0 +1,71 @@ +#Must be 16 digits (replace with your own creation !) +secretKey=7070200000000007 + + + +#Elastic Search configurations +elasticsearch.cluster.name=shopizer +elasticsearch.mode=remote +elasticsearch.server.host=es-server +elasticsearch.server.protocole=http +elasticsearch.server.port=9200 +elasticsearch.server.proxy.user= +elasticsearch.server.proxy.password= +elasticsearch.security.enabled=false +elasticsearch.security.user=elastic +elasticsearch.security.password=changeme + + +#Infinispan configuration +config.cms.store.location=/tmp/store +config.cms.files.location=/tmp/repos + + +# Which CMS method to use +# default = infinispan +# httpd = requires http server +# aws = AWS S3 -> See AWS S3 configuration below +config.cms.method=default + +config.cms.static.path=/static + +#httpd configuration +#Specifies where htdocs repository is located +config.cms.http.path.location= + +#AWS S3 configuration +#Name of bucket files +#See regions here https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html +#Credentials must be set as environment variables when launching Shopizer +#AWS_ACCESS_KEY_ID= +#AWS_SECRETE_ACCESS_KEY= +config.cms.aws.bucket= +config.cms.aws.region= + +config.cms.gcp.bucket=shopizer-demo + +config.emailSender=default +config.emailSender.region= + +#Shipping activated in the system ? +config.displayShipping=true + + +#Google map API key +#For using priceByDistance shipping module +config.shippingDistancePreProcessor.apiKey= +config.shippingDistancePreProcessor.acceptedZones=QC,ON,AB,NY,MA + +#checkout and signup address validation +#see : https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete-addressform +#Should be passed as an environment key +config.googleMapsKey= + +#recaptcha https://developers.google.com/recaptcha/ +config.recaptcha.secretKey= +config.recaptcha.siteKey= + +#shipping rules +config.shipping.rule.priceByDistance=PriceByDistance.drl +config.shipping.rule.shippingModuleDecision=ShippingDecision.drl + diff --git a/sm-core/src/main/resources/profiles/local/shopizer-core.properties b/sm-core/src/main/resources/profiles/local/shopizer-core.properties new file mode 100755 index 0000000000..e6ebdb48fd --- /dev/null +++ b/sm-core/src/main/resources/profiles/local/shopizer-core.properties @@ -0,0 +1,106 @@ +#Runs with a local cms hhtpd web. See https://github.com/shopizer-ecommerce/shopizer-docker-compose nginx + + +#Must be 16 digits (replace with your own creation !) +secretKey=7070200000000007 + +#Elastic Search configurations +elasticsearch.cluster.name=shopizer +elasticsearch.mode=remote +#coma seperated host values +elasticsearch.server.host=localhost +elasticsearch.server.protocole=http +elasticsearch.server.port=9200 +elasticsearch.server.proxy.user= +elasticsearch.server.proxy.password= +#enable if ES is secured (by default it is not) +elasticsearch.security.enabled=false +elasticsearch.security.user=elastic +elasticsearch.security.password=changeme + + +search.clusterName=opensearch-cluster +#search.jksAbsolutePath=/Users/csa/Documents/dev/processes/open-search/config/testnode.jks +search.jksAbsolutePath= + +#Languages to be configured for the search engine. Too much will impact the size and how indexes are built +search.searchLanguages=en,fr + +search.host[0].scheme=http +search.host[0].host=localhost +search.host[0].port=9200 +#search.host[1].scheme=http +#search.host[1].host=host-2 +#search.host[1].port=9200 + +# Which CMS method to use [ default | httpd | aws | gcp ] +# default = infinispan +# httpd = requires http server +# aws = AWS S3 -> See AWS S3 configuration below +# gcp = Google Cloud Storage + +config.cms.method=httpd +config.cms.contentUrl=http://localhost:80 +config.cms.static.path=/static + + +#Infinispan configuration +#Specifies where files are located +config.cms.store.location=./files/store +config.cms.files.location=./files/repos + +#httpd configuration +#Specifies where htdocs repository is located +config.cms.http.path.location=/Users/carlsamson/Documents/dev/processes/docker-compose/shopizer-docker-compose/outer-architecture/nginx/web + + +#AWS S3 configuration +#Name of bucket files +#See regions here https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html +#Credentials must be set as environment variables when launching Shopizer +#AWS_ACCESS_KEY_ID= +#AWS_SECRETE_ACCESS_KEY= +config.cms.aws.bucket= +config.cms.aws.region=us-east-1 + +#GCP Cloud Storage configuration +#Name of the bucket file +#If the bucket does not exists it will be created +#export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/[FILE_NAME].json" +config.cms.gcp.bucket= + +#You need an AWS access key ID and AWS secret access key to access Amazon SES using an SDK +#AWS keys need to be specified in environment variables +# -e AWS_ACCESS_KEY_ID=YOUR-ACCESS-KEY \ +# -e AWS_SECRET_ACCESS_KEY=YOUR-SECRET-ACCESS-KEY \ +#Email implementation [default | ses] +#default=SpringHtmlEmailSender - through SMTP server and requires configurations from admin console +#ses=AWS SES service +config.emailSender=default +config.emailSender.region=US_EAST_1 + +#Shipping activated in the system ? +config.displayShipping=true + +#Google map API key +#For using priceByDistance shipping module +#See shopizer-core-modules.xml +config.shippingDistancePreProcessor.apiKey= +config.shippingDistancePreProcessor.acceptedZones=QC,ON,AB,NY,MA + +#checkout and signup address validation +#see : https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete-addressform +#Should be passed as an environment key +config.googleMapsKey= + +#recaptcha https://developers.google.com/recaptcha/ +#testing keys +config.recaptcha.secretKey=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe +config.recaptcha.siteKey=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI + +#shipping rules +config.shipping.rule.priceByDistance=PriceByDistance.drl +config.shipping.rule.shippingModuleDecision=ShippingDecision.drl + +#Creates default database data (should always be true) +db.init.data=true diff --git a/sm-core/src/main/resources/profiles/mysql/shopizer-core.properties b/sm-core/src/main/resources/profiles/mysql/shopizer-core.properties new file mode 100644 index 0000000000..96e8b9cdfa --- /dev/null +++ b/sm-core/src/main/resources/profiles/mysql/shopizer-core.properties @@ -0,0 +1,131 @@ +#Must be 16 digits (replace with your own creation !) +secretKey=7070200000000007 + +# commented out properties need to be set from an environment variable +# when using this profile when running docker based application +# +# example of environment variables when running docker image using aws +# +# docker run -d -p 80:8080 shopizerecomm/shopizer:latest \ +# -e SPRING_PROFILES_ACTIVE=cloud \ +# -e JAVA_OPTS=-Xms1024m -Xmx1024m \ +# -e elasticsearch.server.host=x.x.x.x \ +# -e elasticsearch.server.port=9200 \ +# -e elasticsearch.server.protocole=http \ +# -e db.jdbcUrl=jdbc:mysql://x.x.x.x:3306/SALESMANAGER?autoReconnect=true&serverTimeZone=UTC&useUnicode=true&characterEncoding=UTF-8 \ +# -e db.user=shopizer_databaseb_user \ +# -e db.password=shopizer_databaseb_password \ +# -e config.cms.method=aws \ +# -e config.cms.contentUrl=https://s3.ca-central-1.amazonaws.com/bucketname \ +# -e GOOGLE_APPLICATION_CREDENTIALS=NO \ +# -e AWS_ACCESS_KEY_ID=YOUR-ACCESS-KEY \ +# -e AWS_SECRET_ACCESS_KEY=YOUR-SECRET-ACCESS-KEY \ +# -e config.cms.gcp.bucket=NO \ +# -e config.cms.aws.bucket=bucketname \ +# -e config.cms.aws.region=ca-central-1 \ +# -e elasticsearch.security.password=NO \ +# -e config.displayShipping=true \ +# -e config.googleMapsKey=GOOGLE-MAPS-KEY \ +# -e config.recaptcha.secretKey=RECAPTCHA-KEY \ +# -e config.recaptcha.siteKey=RECAPTCHA-SITE-KEY \ +# -e config.shippingDistancePreProcessor.acceptedZones=QC,ON,NB,XX,YY \ +# -e config.shippingDistancePreProcessor.apiKey=GOOGLE-MAPS-KEY \ +# -e config.emailSender=ses \ +# -e config.emailSender.region=US_EAST_1 \ + + +#Elastic Search configurations +elasticsearch.cluster.name=shopizer +elasticsearch.mode=remote +elasticsearch.server.host=localhost +elasticsearch.server.protocole=http +elasticsearch.server.port=9200 +elasticsearch.server.proxy.user= +elasticsearch.server.proxy.password= +elasticsearch.security.enabled=false +elasticsearch.security.user=elastic + +###Search starter configuration instead of config above +search.credentials.username=admin +search.credentials.password=admin + +search.clusterName=opensearch-cluster +#search.jksAbsolutePath=/Users/csa/Documents/dev/processes/open-search/config/testnode.jks +search.jksAbsolutePath= + +#Languages to be configured for the search engine. Too much will impact the size and how indexes are built +search.searchLanguages=en,fr + +search.host[0].scheme=http +search.host[0].host=0.0.0.0 +search.host[0].port=9200 +search.host[1].scheme=http +search.host[1].host=0.0.0.0 +search.host[1].port=9201 + +# Which CMS method to use +# default = infinispan +# httpd = requires http server +# aws = AWS S3 -> See AWS S3 configuration below +# gcp + +config.cms.method=default +config.cms.contentUrl=http://localhost:8080 +config.cms.static.path=/static + + +#Infinispan configuration +#Specifies where files are located +config.cms.store.location=./files/store +config.cms.files.location=./files/repos + +#httpd configuration +#Specifies where htdocs repository is located +config.cms.http.path.location= + +config.cms.static.path=/static + +#AWS S3 configuration +#Name of bucket files +#See regions here https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html +#Credentials must be set as environment variables when launching Shopizer +#AWS_ACCESS_KEY_ID= +#AWS_SECRETE_ACCESS_KEY= +#config.cms.contentUrl=https://s3.ca-central-1.amazonaws.com/shopizer-lightsail +config.cms.aws.bucket= +config.cms.aws.region= + +config.cms.gcp.bucket= + +#You need an AWS access key ID and AWS secret access key to access Amazon SES using an SDK +#AWS keys need to be specified in environment variables, see above +#default is using smtp and requires configurations from admin console +#Email implementation [default | ses] +config.emailSender=ses +config.emailSender.region=US_EAST_1 + +#Shipping activated in the system ? +config.displayShipping=true + +#Google map API key +#For using priceByDistance shipping module +#See shopizer-core-modules.xml +config.shippingDistancePreProcessor.apiKey= +config.shippingDistancePreProcessor.acceptedZones=QC,ON,AB,NY,MA + +#checkout and signup address validation +#see : https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete-addressform +#Should be passed as an environment key +config.googleMapsKey= + +#recaptcha https://developers.google.com/recaptcha/ +#testing keys +config.recaptcha.secretKey=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe +config.recaptcha.siteKey=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI + +#shipping rules +config.shipping.rule.priceByDistance=PriceByDistance.drl +config.shipping.rule.shippingModuleDecision=ShippingDecision.drl + +#Creates default database data (should always be true) +db.init.data=true \ No newline at end of file diff --git a/sm-core/src/main/resources/reference/GeoLite2-City.mmdb b/sm-core/src/main/resources/reference/GeoLite2-City.mmdb new file mode 100755 index 0000000000..5156153d50 Binary files /dev/null and b/sm-core/src/main/resources/reference/GeoLite2-City.mmdb differ diff --git a/sm-core/src/main/resources/reference/integrationmodules.json b/sm-core/src/main/resources/reference/integrationmodules.json new file mode 100755 index 0000000000..4c83596363 --- /dev/null +++ b/sm-core/src/main/resources/reference/integrationmodules.json @@ -0,0 +1,121 @@ +[ + { + "module": "SHIPPING", + "code": "usps", + "version":"", + "regions": ["US"], + "image":"usps.jpg", + "configuration":[{"env":"TEST","scheme":"http","host":"testing.shippingapis.com","port":"80","uri":"/ShippingAPI.dll"},{"env":"PROD","scheme":"http","host":"production.shippingapis.com","port":"80","uri":"/ShippingAPI.dll"}] + + }, + { + "module": "SHIPPING", + "code": "canadapost", + "version":"", + "regions": ["CA"], + "image":"canadapost.jpg", + "configuration":[{"env":"TEST","scheme":"https","host":"ct.soa-gw.canadapost.ca","port":"443","uri":"/rs/ship/price"},{"env":"PROD","scheme":"https","host":"soa-gw.canadapost.ca","port":"443","uri":"/rs/ship/price"}] + + }, + { + "module": "SHIPPING", + "code": "ups", + "version":"", + "regions": ["US","CA","FR","GB"], + "image":"ups.jpg", + "configuration":[{"env":"TEST","scheme":"https","host":"wwwcie.ups.com","port":"443","uri":"/ups.app/xml/Rate"},{"env":"PROD","scheme":"https","host":"onlinetools.ups.com","port":"443","uri":"/xml/Rate"}], + "details":{"01":"UPS Next Day Air","02":"UPS Second Day Air","03":"UPS Ground","07":"UPS Worldwide Express","08":"UPS Worldwide Expedited","11":"UPS Standard","12":"UPS Three-Day Select","13":"UPS Next Day Air Saver","14":"UPS Next Day Air Early A.M.","54":"UPS Worldwide Express Plus","59":"UPS Second Day Air A.M.","69":"UPS Saver"} + + }, + { + "module": "SHIPPING", + "code": "weightBased", + "customModule":"true", + "version":"1.0", + "regions": ["*"] + }, + { + "module": "SHIPPING", + "code": "customQuotesRules", + "version":"1.0", + "regions": ["*"] + }, + { + "module": "SHIPPING", + "code": "priceByDistance", + "version":"1.0", + "regions": ["*"] + }, + { + "module": "SHIPPING", + "code": "storePickUp", + "version":"1.0", + "regions": ["*"] + }, + { + "module": "PAYMENT", + "code": "moneyorder", + "type":"moneyorder", + "version":"", + "regions": ["*"], + "image":"moneyorder.gif" + }, + { + "module": "PAYMENT", + "code": "paypal-express-checkout", + "type":"paypal", + "version":"104.0", + "regions": ["*"], + "image":"icon-paypal.png", + "configuration":[{"env":"TEST","scheme":"","host":"","port":"","uri":"","config1":"https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token="},{"env":"PROD","scheme":"","host":"","port":"","uri":"","config1":"https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token="}] + + }, + + + { + "module": "PAYMENT", + "code": "beanstream", + "type":"creditcard", + "version":"", + "regions": ["US","CA","GB"], + "image":"beanstream.gif", + "configuration":[{"env":"TEST","scheme":"https","host":"www.beanstream.com","port":"443","uri":"/scripts/process_transaction.asp"},{"env":"PROD","scheme":"https","host":"www.beanstream.com","port":"443","uri":"/scripts/process_transaction.asp"}] + + }, + + + { + "module": "PAYMENT", + "code": "stripe", + "type":"creditcard", + "version":"", + "regions": ["US","CA","GB","AU","FI","DK","IE","NO","SE","ES","PT"], + "image":"stripe.png", + "configuration":[{"env":"TEST","scheme":"https","host":"www.stripe.com","port":"443","uri":"/"},{"env":"PROD","scheme":"https","host":"www.stripe.com","port":"443","uri":"/"}] + + }, + + { + "module": "PAYMENT", + "code": "stripe3", + "type":"creditcard", + "version":"", + "regions": ["US","CA","GB","AU","FI","DK","IE","NO","SE","ES","PT"], + "image":"stripe.png", + "configuration":[{"env":"TEST","scheme":"https","host":"www.stripe.com","port":"443","uri":"/"},{"env":"PROD","scheme":"https","host":"www.stripe.com","port":"443","uri":"/"}] + + }, + + { + "module": "PAYMENT", + "code": "braintree", + "type":"creditcard", + "version":"", + "regions": ["US","CA","GB","AU","FI","DK","IE","NO","SE","AL","AD","AT","BY","BE","BG","HY","CY","CZ","FR","GR","IS","IE","IM","IT","PL","LU","CH","RS","SG","MY","HK","NZ"], + "image":"braintree.jpg", + "configuration":[{"env":"TEST","scheme":"https","host":"NOTREQUIRED","port":"NOTREQUIRED","uri":"NOTREQUIRED"},{"env":"PROD","scheme":"https","host":"NOTREQUIRED","port":"NOTREQUIRED","uri":"NOTREQUIRED"}] + + } + +] + diff --git a/sm-core/src/main/resources/reference/zoneconfig.json b/sm-core/src/main/resources/reference/zoneconfig.json new file mode 100755 index 0000000000..0ab94c1186 --- /dev/null +++ b/sm-core/src/main/resources/reference/zoneconfig.json @@ -0,0 +1,2860 @@ +{ + "en":[ + { + "zoneCode": "AL", + "zoneName": "Alabama", + "countryCode": "US" + }, + { + "zoneCode": "AK", + "zoneName": "Alaska", + "countryCode": "US" + }, + { + "zoneCode": "AS", + "zoneName": "American Samoa", + "countryCode": "US" + }, + { + "zoneCode": "AZ", + "zoneName": "Arizona", + "countryCode": "US" + }, + { + "zoneCode": "AR", + "zoneName": "Arkansas", + "countryCode": "US" + }, + { + "zoneCode": "AF", + "zoneName": "Armed Forces Africa", + "countryCode": "US" + }, + { + "zoneCode": "AA", + "zoneName": "Armed Forces Americas", + "countryCode": "US" + }, + { + "zoneCode": "AC", + "zoneName": "Armed Forces Canada", + "countryCode": "US" + }, + { + "zoneCode": "AE", + "zoneName": "Armed Forces Europe", + "countryCode": "US" + }, + { + "zoneCode": "AM", + "zoneName": "Armed Forces Middle East", + "countryCode": "US" + }, + { + "zoneCode": "AP", + "zoneName": "Armed Forces Pacific", + "countryCode": "US" + }, + { + "zoneCode": "CA", + "zoneName": "California", + "countryCode": "US" + }, + { + "zoneCode": "CO", + "zoneName": "Colorado", + "countryCode": "US" + }, + { + "zoneCode": "CT", + "zoneName": "Connecticut", + "countryCode": "US" + }, + { + "zoneCode": "DE", + "zoneName": "Delaware", + "countryCode": "US" + }, + { + "zoneCode": "DC", + "zoneName": "District of Columbia", + "countryCode": "US" + }, + { + "zoneCode": "FM", + "zoneName": "Federated States Of Micronesia", + "countryCode": "US" + }, + { + "zoneCode": "FL", + "zoneName": "Florida", + "countryCode": "US" + }, + { + "zoneCode": "GA", + "zoneName": "Georgia", + "countryCode": "US" + }, + { + "zoneCode": "GU", + "zoneName": "Guam", + "countryCode": "US" + }, + { + "zoneCode": "HI", + "zoneName": "Hawaii", + "countryCode": "US" + }, + { + "zoneCode": "ID", + "zoneName": "Idaho", + "countryCode": "US" + }, + { + "zoneCode": "IL", + "zoneName": "Illinois", + "countryCode": "US" + }, + { + "zoneCode": "IN", + "zoneName": "Indiana", + "countryCode": "US" + }, + { + "zoneCode": "IA", + "zoneName": "Iowa", + "countryCode": "US" + }, + { + "zoneCode": "KS", + "zoneName": "Kansas", + "countryCode": "US" + }, + { + "zoneCode": "KY", + "zoneName": "Kentucky", + "countryCode": "US" + }, + { + "zoneCode": "LA", + "zoneName": "Louisiana", + "countryCode": "US" + }, + { + "zoneCode": "ME", + "zoneName": "Maine", + "countryCode": "US" + }, + { + "zoneCode": "MH", + "zoneName": "Marshall Islands", + "countryCode": "US" + }, + { + "zoneCode": "MD", + "zoneName": "Maryland", + "countryCode": "US" + }, + { + "zoneCode": "MA", + "zoneName": "Massachusetts", + "countryCode": "US" + }, + { + "zoneCode": "MI", + "zoneName": "Michigan", + "countryCode": "US" + }, + { + "zoneCode": "MN", + "zoneName": "Minnesota", + "countryCode": "US" + }, + { + "zoneCode": "MS", + "zoneName": "Mississippi", + "countryCode": "US" + }, + { + "zoneCode": "MO", + "zoneName": "Missouri", + "countryCode": "US" + }, + { + "zoneCode": "MT", + "zoneName": "Montana", + "countryCode": "US" + }, + { + "zoneCode": "NE", + "zoneName": "Nebraska", + "countryCode": "US" + }, + { + "zoneCode": "NV", + "zoneName": "Nevada", + "countryCode": "US" + }, + { + "zoneCode": "NH", + "zoneName": "New Hampshire", + "countryCode": "US" + }, + { + "zoneCode": "NJ", + "zoneName": "New Jersey", + "countryCode": "US" + }, + { + "zoneCode": "NM", + "zoneName": "New Mexico", + "countryCode": "US" + }, + { + "zoneCode": "NY", + "zoneName": "New York", + "countryCode": "US" + }, + { + "zoneCode": "NC", + "zoneName": "North Carolina", + "countryCode": "US" + }, + { + "zoneCode": "ND", + "zoneName": "North Dakota", + "countryCode": "US" + }, + { + "zoneCode": "MP", + "zoneName": "Northern Mariana Islands", + "countryCode": "US" + }, + { + "zoneCode": "OH", + "zoneName": "Ohio", + "countryCode": "US" + }, + { + "zoneCode": "OK", + "zoneName": "Oklahoma", + "countryCode": "US" + }, + { + "zoneCode": "OR", + "zoneName": "Oregon", + "countryCode": "US" + }, + { + "zoneCode": "PA", + "zoneName": "Pennsylvania", + "countryCode": "US" + }, + { + "zoneCode": "PR", + "zoneName": "Puerto Rico", + "countryCode": "US" + }, + { + "zoneCode": "RI", + "zoneName": "Rhode Island", + "countryCode": "US" + }, + { + "zoneCode": "SC", + "zoneName": "South Carolina", + "countryCode": "US" + }, + { + "zoneCode": "SD", + "zoneName": "South Dakota", + "countryCode": "US" + }, + { + "zoneCode": "TN", + "zoneName": "Tennessee", + "countryCode": "US" + }, + { + "zoneCode": "TX", + "zoneName": "Texas", + "countryCode": "US" + }, + { + "zoneCode": "UT", + "zoneName": "Utah", + "countryCode": "US" + }, + { + "zoneCode": "VT", + "zoneName": "Vermont", + "countryCode": "US" + }, + { + "zoneCode": "VI", + "zoneName": "Virgin Islands", + "countryCode": "US" + }, + { + "zoneCode": "VA", + "zoneName": "Virginia", + "countryCode": "US" + }, + { + "zoneCode": "WA", + "zoneName": "Washington", + "countryCode": "US" + }, + { + "zoneCode": "WV", + "zoneName": "West Virginia", + "countryCode": "US" + }, + { + "zoneCode": "WI", + "zoneName": "Wisconsin", + "countryCode": "US" + }, + { + "zoneCode": "WY", + "zoneName": "Wyoming", + "countryCode": "US" + }, + { + "zoneCode": "AB", + "zoneName": "Alberta", + "countryCode": "CA" + }, + { + "zoneCode": "BC", + "zoneName": "British Columbia", + "countryCode": "CA" + }, + { + "zoneCode": "MB", + "zoneName": "Manitoba", + "countryCode": "CA" + }, + { + "zoneCode": "NF", + "zoneName": "Newfoundland - Labrador", + "countryCode": "CA" + }, + { + "zoneCode": "NB", + "zoneName": "New Brunswick", + "countryCode": "CA" + }, + { + "zoneCode": "NS", + "zoneName": "Nova Scotia", + "countryCode": "CA" + }, + { + "zoneCode": "NT", + "zoneName": "Northwest Territories", + "countryCode": "CA" + }, + { + "zoneCode": "NU", + "zoneName": "Nunavut", + "countryCode": "CA" + }, + { + "zoneCode": "ON", + "zoneName": "Ontario", + "countryCode": "CA" + }, + { + "zoneCode": "PE", + "zoneName": "Prince Edward Island", + "countryCode": "CA" + }, + { + "zoneCode": "QC", + "zoneName": "Quebec", + "countryCode": "CA" + }, + { + "zoneCode": "SK", + "zoneName": "Saskatchewan", + "countryCode": "CA" + }, + { + "zoneCode": "YT", + "zoneName": "Yukon Territory", + "countryCode": "CA" + }, + { + "zoneCode": "NDS", + "zoneName": "Niedersachsen", + "countryCode": "DE" + }, + { + "zoneCode": "BAW", + "zoneName": "Baden-Wrttemberg", + "countryCode": "DE" + }, + { + "zoneCode": "BAY", + "zoneName": "Bayern", + "countryCode": "DE" + }, + { + "zoneCode": "BER", + "zoneName": "Berlin", + "countryCode": "DE" + }, + { + "zoneCode": "BRG", + "zoneName": "Brandenburg", + "countryCode": "DE" + }, + { + "zoneCode": "BRE", + "zoneName": "Bremen", + "countryCode": "DE" + }, + { + "zoneCode": "HAM", + "zoneName": "Hamburg", + "countryCode": "DE" + }, + { + "zoneCode": "HES", + "zoneName": "Hessen", + "countryCode": "DE" + }, + { + "zoneCode": "MEC", + "zoneName": "Mecklenburg-Vorpommern", + "countryCode": "DE" + }, + { + "zoneCode": "NRW", + "zoneName": "Nordrhein-Westfalen", + "countryCode": "DE" + }, + { + "zoneCode": "RHE", + "zoneName": "Rheinland-Pfalz", + "countryCode": "DE" + }, + { + "zoneCode": "SAR", + "zoneName": "Saarland", + "countryCode": "DE" + }, + { + "zoneCode": "SAS", + "zoneName": "Sachsen", + "countryCode": "DE" + }, + { + "zoneCode": "SAC", + "zoneName": "Sachsen-Anhalt", + "countryCode": "DE" + }, + { + "zoneCode": "SCN", + "zoneName": "Schleswig-Holstein", + "countryCode": "DE" + }, + { + "zoneCode": "THE", + "zoneName": "Thringen", + "countryCode": "DE" + }, + { + "zoneCode": "WIAT", + "zoneName": "Wien", + "countryCode": "AT" + }, + { + "zoneCode": "NO", + "zoneName": "Niederosterreich", + "countryCode": "AT" + }, + { + "zoneCode": "OO", + "zoneName": "Oberosterreich", + "countryCode": "AT" + }, + { + "zoneCode": "SB", + "zoneName": "Salzburg", + "countryCode": "AT" + }, + { + "zoneCode": "KN", + "zoneName": "Katen", + "countryCode": "AT" + }, + { + "zoneCode": "ST", + "zoneName": "Steiermark", + "countryCode": "AT" + }, + { + "zoneCode": "TIAT", + "zoneName": "Tirol", + "countryCode": "AT" + }, + { + "zoneCode": "BLAT", + "zoneName": "Burgenland", + "countryCode": "AT" + }, + { + "zoneCode": "VB", + "zoneName": "Voralberg", + "countryCode": "AT" + }, + { + "zoneCode": "AG", + "zoneName": "Aargau", + "countryCode": "CH" + }, + { + "zoneCode": "AI", + "zoneName": "Appenzell Innerrhoden", + "countryCode": "CH" + }, + { + "zoneCode": "ARCH", + "zoneName": "Appenzell Ausserrhoden", + "countryCode": "CH" + }, + { + "zoneCode": "BE", + "zoneName": "Bern", + "countryCode": "CH" + }, + { + "zoneCode": "BL", + "zoneName": "Basel-Landschaft", + "countryCode": "CH" + }, + { + "zoneCode": "BS", + "zoneName": "Basel-Stadt", + "countryCode": "CH" + }, + { + "zoneCode": "FR", + "zoneName": "Freiburg", + "countryCode": "CH" + }, + { + "zoneCode": "GE", + "zoneName": "Genf", + "countryCode": "CH" + }, + { + "zoneCode": "GL", + "zoneName": "Glarus", + "countryCode": "CH" + }, + { + "zoneCode": "GR", + "zoneName": "Graubnden", + "countryCode": "CH" + }, + { + "zoneCode": "JU", + "zoneName": "Jura", + "countryCode": "CH" + }, + { + "zoneCode": "LU", + "zoneName": "Luzern", + "countryCode": "CH" + }, + { + "zoneCode": "NECH", + "zoneName": "Neuenburg", + "countryCode": "CH" + }, + { + "zoneCode": "NW", + "zoneName": "Nidwalden", + "countryCode": "CH" + }, + { + "zoneCode": "OW", + "zoneName": "Obwalden", + "countryCode": "CH" + }, + { + "zoneCode": "SG", + "zoneName": "St. Gallen", + "countryCode": "CH" + }, + { + "zoneCode": "SH", + "zoneName": "Schaffhausen", + "countryCode": "CH" + }, + { + "zoneCode": "SO", + "zoneName": "Solothurn", + "countryCode": "CH" + }, + { + "zoneCode": "SZ", + "zoneName": "Schwyz", + "countryCode": "CH" + }, + { + "zoneCode": "TG", + "zoneName": "Thurgau", + "countryCode": "CH" + }, + { + "zoneCode": "TI", + "zoneName": "Tessin", + "countryCode": "CH" + }, + { + "zoneCode": "UR", + "zoneName": "Uri", + "countryCode": "CH" + }, + { + "zoneCode": "VD", + "zoneName": "Waadt", + "countryCode": "CH" + }, + { + "zoneCode": "VS", + "zoneName": "Wallis", + "countryCode": "CH" + }, + { + "zoneCode": "ZG", + "zoneName": "Zug", + "countryCode": "CH" + }, + { + "zoneCode": "ZH", + "zoneName": "Zrich", + "countryCode": "CH" + }, + { + "zoneCode": "ACorua", + "zoneName": "A Corua", + "countryCode": "ES" + }, + { + "zoneCode": "Alava", + "zoneName": "Alava", + "countryCode": "ES" + }, + { + "zoneCode": "Albacete", + "zoneName": "Albacete", + "countryCode": "ES" + }, + { + "zoneCode": "Alicante", + "zoneName": "Alicante", + "countryCode": "ES" + }, + { + "zoneCode": "Almeria", + "zoneName": "Almeria", + "countryCode": "ES" + }, + { + "zoneCode": "Asturias", + "zoneName": "Asturias", + "countryCode": "ES" + }, + { + "zoneCode": "Avila", + "zoneName": "Avila", + "countryCode": "ES" + }, + { + "zoneCode": "Badajoz", + "zoneName": "Badajoz", + "countryCode": "ES" + }, + { + "zoneCode": "Baleares", + "zoneName": "Baleares", + "countryCode": "ES" + }, + { + "zoneCode": "Barcelona", + "zoneName": "Barcelona", + "countryCode": "ES" + }, + { + "zoneCode": "Burgos", + "zoneName": "Burgos", + "countryCode": "ES" + }, + { + "zoneCode": "Caceres", + "zoneName": "Caceres", + "countryCode": "ES" + }, + { + "zoneCode": "Cadiz", + "zoneName": "Cadiz", + "countryCode": "ES" + }, + { + "zoneCode": "Cantabria", + "zoneName": "Cantabria", + "countryCode": "ES" + }, + { + "zoneCode": "Castellon", + "zoneName": "Castellon", + "countryCode": "ES" + }, + { + "zoneCode": "Ceuta", + "zoneName": "Ceuta", + "countryCode": "ES" + }, + { + "zoneCode": "CiudadReal", + "zoneName": "Ciudad Real", + "countryCode": "ES" + }, + { + "zoneCode": "Cordoba", + "zoneName": "Cordoba", + "countryCode": "ES" + }, + { + "zoneCode": "Cuenca", + "zoneName": "Cuenca", + "countryCode": "ES" + }, + { + "zoneCode": "Girona", + "zoneName": "Girona", + "countryCode": "ES" + }, + { + "zoneCode": "Granada", + "zoneName": "Granada", + "countryCode": "ES" + }, + { + "zoneCode": "Guadalajara", + "zoneName": "Guadalajara", + "countryCode": "ES" + }, + { + "zoneCode": "Guipuzcoa", + "zoneName": "Guipuzcoa", + "countryCode": "ES" + }, + { + "zoneCode": "Huelva", + "zoneName": "Huelva", + "countryCode": "ES" + }, + { + "zoneCode": "Huesca", + "zoneName": "Huesca", + "countryCode": "ES" + }, + { + "zoneCode": "Jaen", + "zoneName": "Jaen", + "countryCode": "ES" + }, + { + "zoneCode": "LaRioja", + "zoneName": "La Rioja", + "countryCode": "ES" + }, + { + "zoneCode": "LasPalmas", + "zoneName": "Las Palmas", + "countryCode": "ES" + }, + { + "zoneCode": "Leon", + "zoneName": "Leon", + "countryCode": "ES" + }, + { + "zoneCode": "Lleida", + "zoneName": "Lleida", + "countryCode": "ES" + }, + { + "zoneCode": "Lugo", + "zoneName": "Lugo", + "countryCode": "ES" + }, + { + "zoneCode": "Madrid", + "zoneName": "Madrid", + "countryCode": "ES" + }, + { + "zoneCode": "Malaga", + "zoneName": "Malaga", + "countryCode": "ES" + }, + { + "zoneCode": "Melilla", + "zoneName": "Melilla", + "countryCode": "ES" + }, + { + "zoneCode": "Murcia", + "zoneName": "Murcia", + "countryCode": "ES" + }, + { + "zoneCode": "Navarra", + "zoneName": "Navarra", + "countryCode": "ES" + }, + { + "zoneCode": "Ourense", + "zoneName": "Ourense", + "countryCode": "ES" + }, + { + "zoneCode": "Palencia", + "zoneName": "Palencia", + "countryCode": "ES" + }, + { + "zoneCode": "Pontevedra", + "zoneName": "Pontevedra", + "countryCode": "ES" + }, + { + "zoneCode": "Salamanca", + "zoneName": "Salamanca", + "countryCode": "ES" + }, + { + "zoneCode": "SantaCruzdeTenerife", + "zoneName": "Santa Cruz de Tenerife", + "countryCode": "ES" + }, + { + "zoneCode": "Segovia", + "zoneName": "Segovia", + "countryCode": "ES" + }, + { + "zoneCode": "Sevilla", + "zoneName": "Sevilla", + "countryCode": "ES" + }, + { + "zoneCode": "Soria", + "zoneName": "Soria", + "countryCode": "ES" + }, + { + "zoneCode": "Tarragona", + "zoneName": "Tarragona", + "countryCode": "ES" + }, + { + "zoneCode": "Teruel", + "zoneName": "Teruel", + "countryCode": "ES" + }, + { + "zoneCode": "Toledo", + "zoneName": "Toledo", + "countryCode": "ES" + }, + { + "zoneCode": "Valencia", + "zoneName": "Valencia", + "countryCode": "ES" + }, + { + "zoneCode": "Valladolid", + "zoneName": "Valladolid", + "countryCode": "ES" + }, + { + "zoneCode": "Vizcaya", + "zoneName": "Vizcaya", + "countryCode": "ES" + }, + { + "zoneCode": "Zamora", + "zoneName": "Zamora", + "countryCode": "ES" + }, + { + "zoneCode": "Zaragoza", + "zoneName": "Zaragoza", + "countryCode": "ES" + }, + { + "zoneCode": "ACT", + "zoneName": "Australian Capital Territory", + "countryCode": "AU" + }, + { + "zoneCode": "NSW", + "zoneName": "New South Wales", + "countryCode": "AU" + }, + { + "zoneCode": "NTAU", + "zoneName": "Northern Territory", + "countryCode": "AU" + }, + { + "zoneCode": "QLD", + "zoneName": "Queensland", + "countryCode": "AU" + }, + { + "zoneCode": "SA", + "zoneName": "South Australia", + "countryCode": "AU" + }, + { + "zoneCode": "TAS", + "zoneName": "Tasmania", + "countryCode": "AU" + }, + { + "zoneCode": "VIC", + "zoneName": "Victoria", + "countryCode": "AU" + }, + { + "zoneCode": "WAAU", + "zoneName": "Western Australia", + "countryCode": "AU" + } , + { + "zoneCode": "ASU", + "zoneName": "Asuncion", + "countryCode": "PY" + }, + { + "zoneCode": "CEN", + "zoneName": "Central", + "countryCode": "PY" + }, + { + "zoneCode": "OTR", + "zoneName": "Other", + "countryCode": "PY" + } +] , + + "fr":[ + { + "zoneCode": "AL", + "zoneName": "Alabama", + "countryCode": "US" + }, + { + "zoneCode": "AK", + "zoneName": "Alaska", + "countryCode": "US" + }, + { + "zoneCode": "AS", + "zoneName": "American Samoa", + "countryCode": "US" + }, + { + "zoneCode": "AZ", + "zoneName": "Arizona", + "countryCode": "US" + }, + { + "zoneCode": "AR", + "zoneName": "Arkansas", + "countryCode": "US" + }, + { + "zoneCode": "AF", + "zoneName": "Armed Forces Africa", + "countryCode": "US" + }, + { + "zoneCode": "AA", + "zoneName": "Armed Forces Americas", + "countryCode": "US" + }, + { + "zoneCode": "AC", + "zoneName": "Armed Forces Canada", + "countryCode": "US" + }, + { + "zoneCode": "AE", + "zoneName": "Armed Forces Europe", + "countryCode": "US" + }, + { + "zoneCode": "AM", + "zoneName": "Armed Forces Middle East", + "countryCode": "US" + }, + { + "zoneCode": "AP", + "zoneName": "Armed Forces Pacific", + "countryCode": "US" + }, + { + "zoneCode": "CA", + "zoneName": "Californie", + "countryCode": "US" + }, + { + "zoneCode": "CO", + "zoneName": "Colorado", + "countryCode": "US" + }, + { + "zoneCode": "CT", + "zoneName": "Connecticut", + "countryCode": "US" + }, + { + "zoneCode": "DE", + "zoneName": "Delaware", + "countryCode": "US" + }, + { + "zoneCode": "DC", + "zoneName": "District de Columbia", + "countryCode": "US" + }, + { + "zoneCode": "FM", + "zoneName": "Federated States Of Micronesia", + "countryCode": "US" + }, + { + "zoneCode": "FL", + "zoneName": "Floride", + "countryCode": "US" + }, + { + "zoneCode": "GA", + "zoneName": "Georgie", + "countryCode": "US" + }, + { + "zoneCode": "GU", + "zoneName": "Guam", + "countryCode": "US" + }, + { + "zoneCode": "HI", + "zoneName": "Hawaii", + "countryCode": "US" + }, + { + "zoneCode": "ID", + "zoneName": "Idaho", + "countryCode": "US" + }, + { + "zoneCode": "IL", + "zoneName": "Illinois", + "countryCode": "US" + }, + { + "zoneCode": "IN", + "zoneName": "Indiana", + "countryCode": "US" + }, + { + "zoneCode": "IA", + "zoneName": "Iowa", + "countryCode": "US" + }, + { + "zoneCode": "KS", + "zoneName": "Kansas", + "countryCode": "US" + }, + { + "zoneCode": "KY", + "zoneName": "Kentucky", + "countryCode": "US" + }, + { + "zoneCode": "LA", + "zoneName": "Louisiane", + "countryCode": "US" + }, + { + "zoneCode": "ME", + "zoneName": "Maine", + "countryCode": "US" + }, + { + "zoneCode": "MH", + "zoneName": "Marshall Islands", + "countryCode": "US" + }, + { + "zoneCode": "MD", + "zoneName": "Maryland", + "countryCode": "US" + }, + { + "zoneCode": "MA", + "zoneName": "Massachusetts", + "countryCode": "US" + }, + { + "zoneCode": "MI", + "zoneName": "Michigan", + "countryCode": "US" + }, + { + "zoneCode": "MN", + "zoneName": "Minnesota", + "countryCode": "US" + }, + { + "zoneCode": "MS", + "zoneName": "Mississippi", + "countryCode": "US" + }, + { + "zoneCode": "MO", + "zoneName": "Missouri", + "countryCode": "US" + }, + { + "zoneCode": "MT", + "zoneName": "Montana", + "countryCode": "US" + }, + { + "zoneCode": "NE", + "zoneName": "Nebraska", + "countryCode": "US" + }, + { + "zoneCode": "NV", + "zoneName": "Nevada", + "countryCode": "US" + }, + { + "zoneCode": "NH", + "zoneName": "Nouveau Hampshire", + "countryCode": "US" + }, + { + "zoneCode": "NJ", + "zoneName": "New Jersey", + "countryCode": "US" + }, + { + "zoneCode": "NM", + "zoneName": "Nouveau Mexique", + "countryCode": "US" + }, + { + "zoneCode": "NY", + "zoneName": "New York", + "countryCode": "US" + }, + { + "zoneCode": "NC", + "zoneName": "Caroline du Nord", + "countryCode": "US" + }, + { + "zoneCode": "ND", + "zoneName": "Dakota du Nord", + "countryCode": "US" + }, + { + "zoneCode": "MP", + "zoneName": "Northern Mariana Islands", + "countryCode": "US" + }, + { + "zoneCode": "OH", + "zoneName": "Ohio", + "countryCode": "US" + }, + { + "zoneCode": "OK", + "zoneName": "Oklahoma", + "countryCode": "US" + }, + { + "zoneCode": "OR", + "zoneName": "Oregon", + "countryCode": "US" + }, + { + "zoneCode": "PA", + "zoneName": "Pennsylvanie", + "countryCode": "US" + }, + { + "zoneCode": "PR", + "zoneName": "Puerto Rico", + "countryCode": "US" + }, + { + "zoneCode": "RI", + "zoneName": "Rhode Island", + "countryCode": "US" + }, + { + "zoneCode": "SC", + "zoneName": "Caroline du Sud", + "countryCode": "US" + }, + { + "zoneCode": "SD", + "zoneName": "Dakota du Sud", + "countryCode": "US" + }, + { + "zoneCode": "TN", + "zoneName": "Tennessee", + "countryCode": "US" + }, + { + "zoneCode": "TX", + "zoneName": "Texas", + "countryCode": "US" + }, + { + "zoneCode": "UT", + "zoneName": "Utah", + "countryCode": "US" + }, + { + "zoneCode": "VT", + "zoneName": "Vermont", + "countryCode": "US" + }, + { + "zoneCode": "VI", + "zoneName": "Virgin Islands", + "countryCode": "US" + }, + { + "zoneCode": "VA", + "zoneName": "Virginie", + "countryCode": "US" + }, + { + "zoneCode": "WA", + "zoneName": "Washington", + "countryCode": "US" + }, + { + "zoneCode": "WV", + "zoneName": "West Virginia", + "countryCode": "US" + }, + { + "zoneCode": "WI", + "zoneName": "Wisconsin", + "countryCode": "US" + }, + { + "zoneCode": "WY", + "zoneName": "Wyoming", + "countryCode": "US" + }, + { + "zoneCode": "AB", + "zoneName": "Alberta", + "countryCode": "CA" + }, + { + "zoneCode": "BC", + "zoneName": "Colombie Britanique", + "countryCode": "CA" + }, + { + "zoneCode": "MB", + "zoneName": "Manitoba", + "countryCode": "CA" + }, + { + "zoneCode": "NF", + "zoneName": "Terre-Neuve - Labrador", + "countryCode": "CA" + }, + { + "zoneCode": "NB", + "zoneName": "Nouveau Brunswick", + "countryCode": "CA" + }, + { + "zoneCode": "NS", + "zoneName": "Nouvelle Écosse", + "countryCode": "CA" + }, + { + "zoneCode": "NT", + "zoneName": "Territores du Nord-Ouest", + "countryCode": "CA" + }, + { + "zoneCode": "NU", + "zoneName": "Nunavut", + "countryCode": "CA" + }, + { + "zoneCode": "ON", + "zoneName": "Ontario", + "countryCode": "CA" + }, + { + "zoneCode": "PE", + "zoneName": "Île-du-Prince-Édouard", + "countryCode": "CA" + }, + { + "zoneCode": "QC", + "zoneName": "Québec", + "countryCode": "CA" + }, + { + "zoneCode": "SK", + "zoneName": "Saskatchewan", + "countryCode": "CA" + }, + { + "zoneCode": "YT", + "zoneName": "Yukon", + "countryCode": "CA" + }, + { + "zoneCode": "NDS", + "zoneName": "Niedersachsen", + "countryCode": "DE" + }, + { + "zoneCode": "BAW", + "zoneName": "Baden-Wrttemberg", + "countryCode": "DE" + }, + { + "zoneCode": "BAY", + "zoneName": "Bayern", + "countryCode": "DE" + }, + { + "zoneCode": "BER", + "zoneName": "Berlin", + "countryCode": "DE" + }, + { + "zoneCode": "BRG", + "zoneName": "Brandenburg", + "countryCode": "DE" + }, + { + "zoneCode": "BRE", + "zoneName": "Bremen", + "countryCode": "DE" + }, + { + "zoneCode": "HAM", + "zoneName": "Hamburg", + "countryCode": "DE" + }, + { + "zoneCode": "HES", + "zoneName": "Hessen", + "countryCode": "DE" + }, + { + "zoneCode": "MEC", + "zoneName": "Mecklenburg-Vorpommern", + "countryCode": "DE" + }, + { + "zoneCode": "NRW", + "zoneName": "Nordrhein-Westfalen", + "countryCode": "DE" + }, + { + "zoneCode": "RHE", + "zoneName": "Rheinland-Pfalz", + "countryCode": "DE" + }, + { + "zoneCode": "SAR", + "zoneName": "Saarland", + "countryCode": "DE" + }, + { + "zoneCode": "SAS", + "zoneName": "Sachsen", + "countryCode": "DE" + }, + { + "zoneCode": "SAC", + "zoneName": "Sachsen-Anhalt", + "countryCode": "DE" + }, + { + "zoneCode": "SCN", + "zoneName": "Schleswig-Holstein", + "countryCode": "DE" + }, + { + "zoneCode": "THE", + "zoneName": "Thringen", + "countryCode": "DE" + }, + { + "zoneCode": "WIAT", + "zoneName": "Wien", + "countryCode": "AT" + }, + { + "zoneCode": "NO", + "zoneName": "Niederosterreich", + "countryCode": "AT" + }, + { + "zoneCode": "OO", + "zoneName": "Oberosterreich", + "countryCode": "AT" + }, + { + "zoneCode": "SB", + "zoneName": "Salzburg", + "countryCode": "AT" + }, + { + "zoneCode": "KN", + "zoneName": "Karten", + "countryCode": "AT" + }, + { + "zoneCode": "ST", + "zoneName": "Steiermark", + "countryCode": "AT" + }, + { + "zoneCode": "TIAT", + "zoneName": "Tirol", + "countryCode": "AT" + }, + { + "zoneCode": "BLAT", + "zoneName": "Burgenland", + "countryCode": "AT" + }, + { + "zoneCode": "VB", + "zoneName": "Voralberg", + "countryCode": "AT" + }, + { + "zoneCode": "AG", + "zoneName": "Aargau", + "countryCode": "CH" + }, + { + "zoneCode": "AI", + "zoneName": "Appenzell Innerrhoden", + "countryCode": "CH" + }, + { + "zoneCode": "ARCH", + "zoneName": "Appenzell Ausserrhoden", + "countryCode": "CH" + }, + { + "zoneCode": "BE", + "zoneName": "Bern", + "countryCode": "CH" + }, + { + "zoneCode": "BL", + "zoneName": "Basel-Landschaft", + "countryCode": "CH" + }, + { + "zoneCode": "BS", + "zoneName": "Basel-Stadt", + "countryCode": "CH" + }, + { + "zoneCode": "FR", + "zoneName": "Freiburg", + "countryCode": "CH" + }, + { + "zoneCode": "GE", + "zoneName": "Genf", + "countryCode": "CH" + }, + { + "zoneCode": "GL", + "zoneName": "Glarus", + "countryCode": "CH" + }, + { + "zoneCode": "GR", + "zoneName": "Graubnden", + "countryCode": "CH" + }, + { + "zoneCode": "JU", + "zoneName": "Jura", + "countryCode": "CH" + }, + { + "zoneCode": "LU", + "zoneName": "Luzern", + "countryCode": "CH" + }, + { + "zoneCode": "NECH", + "zoneName": "Neuenburg", + "countryCode": "CH" + }, + { + "zoneCode": "NW", + "zoneName": "Nidwalden", + "countryCode": "CH" + }, + { + "zoneCode": "OW", + "zoneName": "Obwalden", + "countryCode": "CH" + }, + { + "zoneCode": "SG", + "zoneName": "St. Gallen", + "countryCode": "CH" + }, + { + "zoneCode": "SH", + "zoneName": "Schaffhausen", + "countryCode": "CH" + }, + { + "zoneCode": "SO", + "zoneName": "Solothurn", + "countryCode": "CH" + }, + { + "zoneCode": "SZ", + "zoneName": "Schwyz", + "countryCode": "CH" + }, + { + "zoneCode": "TG", + "zoneName": "Thurgau", + "countryCode": "CH" + }, + { + "zoneCode": "TI", + "zoneName": "Tessin", + "countryCode": "CH" + }, + { + "zoneCode": "UR", + "zoneName": "Uri", + "countryCode": "CH" + }, + { + "zoneCode": "VD", + "zoneName": "Waadt", + "countryCode": "CH" + }, + { + "zoneCode": "VS", + "zoneName": "Wallis", + "countryCode": "CH" + }, + { + "zoneCode": "ZG", + "zoneName": "Zug", + "countryCode": "CH" + }, + { + "zoneCode": "ZH", + "zoneName": "Zrich", + "countryCode": "CH" + }, + { + "zoneCode": "A Corua", + "zoneName": "A Corua", + "countryCode": "ES" + }, + { + "zoneCode": "Alava", + "zoneName": "Alava", + "countryCode": "ES" + }, + { + "zoneCode": "Albacete", + "zoneName": "Albacete", + "countryCode": "ES" + }, + { + "zoneCode": "Alicante", + "zoneName": "Alicante", + "countryCode": "ES" + }, + { + "zoneCode": "Almeria", + "zoneName": "Almeria", + "countryCode": "ES" + }, + { + "zoneCode": "Asturias", + "zoneName": "Asturias", + "countryCode": "ES" + }, + { + "zoneCode": "Avila", + "zoneName": "Avila", + "countryCode": "ES" + }, + { + "zoneCode": "Badajoz", + "zoneName": "Badajoz", + "countryCode": "ES" + }, + { + "zoneCode": "Baleares", + "zoneName": "Baleares", + "countryCode": "ES" + }, + { + "zoneCode": "Barcelona", + "zoneName": "Barcelona", + "countryCode": "ES" + }, + { + "zoneCode": "Burgos", + "zoneName": "Burgos", + "countryCode": "ES" + }, + { + "zoneCode": "Caceres", + "zoneName": "Caceres", + "countryCode": "ES" + }, + { + "zoneCode": "Cadiz", + "zoneName": "Cadiz", + "countryCode": "ES" + }, + { + "zoneCode": "Cantabria", + "zoneName": "Cantabria", + "countryCode": "ES" + }, + { + "zoneCode": "Castellon", + "zoneName": "Castellon", + "countryCode": "ES" + }, + { + "zoneCode": "Ceuta", + "zoneName": "Ceuta", + "countryCode": "ES" + }, + { + "zoneCode": "CiudadReal", + "zoneName": "Ciudad Real", + "countryCode": "ES" + }, + { + "zoneCode": "Cordoba", + "zoneName": "Cordoba", + "countryCode": "ES" + }, + { + "zoneCode": "Cuenca", + "zoneName": "Cuenca", + "countryCode": "ES" + }, + { + "zoneCode": "Girona", + "zoneName": "Girona", + "countryCode": "ES" + }, + { + "zoneCode": "Granada", + "zoneName": "Granada", + "countryCode": "ES" + }, + { + "zoneCode": "Guadalajara", + "zoneName": "Guadalajara", + "countryCode": "ES" + }, + { + "zoneCode": "Guipuzcoa", + "zoneName": "Guipuzcoa", + "countryCode": "ES" + }, + { + "zoneCode": "Huelva", + "zoneName": "Huelva", + "countryCode": "ES" + }, + { + "zoneCode": "Huesca", + "zoneName": "Huesca", + "countryCode": "ES" + }, + { + "zoneCode": "Jaen", + "zoneName": "Jaen", + "countryCode": "ES" + }, + { + "zoneCode": "LaRioja", + "zoneName": "La Rioja", + "countryCode": "ES" + }, + { + "zoneCode": "LasPalmas", + "zoneName": "Las Palmas", + "countryCode": "ES" + }, + { + "zoneCode": "Leon", + "zoneName": "Leon", + "countryCode": "ES" + }, + { + "zoneCode": "Lleida", + "zoneName": "Lleida", + "countryCode": "ES" + }, + { + "zoneCode": "Lugo", + "zoneName": "Lugo", + "countryCode": "ES" + }, + { + "zoneCode": "Madrid", + "zoneName": "Madrid", + "countryCode": "ES" + }, + { + "zoneCode": "Malaga", + "zoneName": "Malaga", + "countryCode": "ES" + }, + { + "zoneCode": "Melilla", + "zoneName": "Melilla", + "countryCode": "ES" + }, + { + "zoneCode": "Murcia", + "zoneName": "Murcia", + "countryCode": "ES" + }, + { + "zoneCode": "Navarra", + "zoneName": "Navarra", + "countryCode": "ES" + }, + { + "zoneCode": "Ourense", + "zoneName": "Ourense", + "countryCode": "ES" + }, + { + "zoneCode": "Palencia", + "zoneName": "Palencia", + "countryCode": "ES" + }, + { + "zoneCode": "Pontevedra", + "zoneName": "Pontevedra", + "countryCode": "ES" + }, + { + "zoneCode": "Salamanca", + "zoneName": "Salamanca", + "countryCode": "ES" + }, + { + "zoneCode": "SantaCruzdeTenerife", + "zoneName": "Santa Cruz de Tenerife", + "countryCode": "ES" + }, + { + "zoneCode": "Segovia", + "zoneName": "Segovia", + "countryCode": "ES" + }, + { + "zoneCode": "Sevilla", + "zoneName": "Sevilla", + "countryCode": "ES" + }, + { + "zoneCode": "Soria", + "zoneName": "Soria", + "countryCode": "ES" + }, + { + "zoneCode": "Tarragona", + "zoneName": "Tarragona", + "countryCode": "ES" + }, + { + "zoneCode": "Teruel", + "zoneName": "Teruel", + "countryCode": "ES" + }, + { + "zoneCode": "Toledo", + "zoneName": "Toledo", + "countryCode": "ES" + }, + { + "zoneCode": "Valencia", + "zoneName": "Valencia", + "countryCode": "ES" + }, + { + "zoneCode": "Valladolid", + "zoneName": "Valladolid", + "countryCode": "ES" + }, + { + "zoneCode": "Vizcaya", + "zoneName": "Vizcaya", + "countryCode": "ES" + }, + { + "zoneCode": "Zamora", + "zoneName": "Zamora", + "countryCode": "ES" + }, + { + "zoneCode": "Zaragoza", + "zoneName": "Zaragoza", + "countryCode": "ES" + }, + { + "zoneCode":"ACT", + "zoneName":"Territoire de la capitale australienne", + "countryCode":"AU" + }, + { + "zoneCode":"WAAU", + "zoneName":"Australie-Occidentale", + "countryCode":"AU" + }, + { + "zoneCode":"SA", + "zoneName":"Australie-Mridionale", + "countryCode":"AU" + }, + { + "zoneCode":"NTAU", + "zoneName":"Territoire du Nord", + "countryCode":"AU" + }, + { + "zoneCode":"VIC", + "zoneName":"Victoria", + "countryCode":"AU" + }, + { + "zoneCode":"TAS", + "zoneName":"Tasmanie", + "countryCode":"AU" + }, + { + "zoneCode":"QLD", + "zoneName":"Queensland", + "countryCode":"AU" + }, + { + "zoneCode":"NSW", + "zoneName":"Nouvelle-Galles du Sud", + "countryCode":"AU" + } + +], + "es":[ + { + "zoneCode": "AL", + "zoneName": "Alabama", + "countryCode": "US" + }, + { + "zoneCode": "AK", + "zoneName": "Alaska", + "countryCode": "US" + }, + { + "zoneCode": "AS", + "zoneName": "American Samoa", + "countryCode": "US" + }, + { + "zoneCode": "AZ", + "zoneName": "Arizona", + "countryCode": "US" + }, + { + "zoneCode": "AR", + "zoneName": "Arkansas", + "countryCode": "US" + }, + { + "zoneCode": "AF", + "zoneName": "Armed Forces Africa", + "countryCode": "US" + }, + { + "zoneCode": "AA", + "zoneName": "Armed Forces Americas", + "countryCode": "US" + }, + { + "zoneCode": "AC", + "zoneName": "Armed Forces Canada", + "countryCode": "US" + }, + { + "zoneCode": "AE", + "zoneName": "Armed Forces Europe", + "countryCode": "US" + }, + { + "zoneCode": "AM", + "zoneName": "Armed Forces Middle East", + "countryCode": "US" + }, + { + "zoneCode": "AP", + "zoneName": "Armed Forces Pacific", + "countryCode": "US" + }, + { + "zoneCode": "CA", + "zoneName": "California", + "countryCode": "US" + }, + { + "zoneCode": "CO", + "zoneName": "Colorado", + "countryCode": "US" + }, + { + "zoneCode": "CT", + "zoneName": "Connecticut", + "countryCode": "US" + }, + { + "zoneCode": "DE", + "zoneName": "Delaware", + "countryCode": "US" + }, + { + "zoneCode": "DC", + "zoneName": "District of Columbia", + "countryCode": "US" + }, + { + "zoneCode": "FM", + "zoneName": "Federated States Of Micronesia", + "countryCode": "US" + }, + { + "zoneCode": "FL", + "zoneName": "Florida", + "countryCode": "US" + }, + { + "zoneCode": "GA", + "zoneName": "Georgia", + "countryCode": "US" + }, + { + "zoneCode": "GU", + "zoneName": "Guam", + "countryCode": "US" + }, + { + "zoneCode": "HI", + "zoneName": "Hawaii", + "countryCode": "US" + }, + { + "zoneCode": "ID", + "zoneName": "Idaho", + "countryCode": "US" + }, + { + "zoneCode": "IL", + "zoneName": "Illinois", + "countryCode": "US" + }, + { + "zoneCode": "IN", + "zoneName": "Indiana", + "countryCode": "US" + }, + { + "zoneCode": "IA", + "zoneName": "Iowa", + "countryCode": "US" + }, + { + "zoneCode": "KS", + "zoneName": "Kansas", + "countryCode": "US" + }, + { + "zoneCode": "KY", + "zoneName": "Kentucky", + "countryCode": "US" + }, + { + "zoneCode": "LA", + "zoneName": "Louisiana", + "countryCode": "US" + }, + { + "zoneCode": "ME", + "zoneName": "Maine", + "countryCode": "US" + }, + { + "zoneCode": "MH", + "zoneName": "Marshall Islands", + "countryCode": "US" + }, + { + "zoneCode": "MD", + "zoneName": "Maryland", + "countryCode": "US" + }, + { + "zoneCode": "MA", + "zoneName": "Massachusetts", + "countryCode": "US" + }, + { + "zoneCode": "MI", + "zoneName": "Michigan", + "countryCode": "US" + }, + { + "zoneCode": "MN", + "zoneName": "Minnesota", + "countryCode": "US" + }, + { + "zoneCode": "MS", + "zoneName": "Mississippi", + "countryCode": "US" + }, + { + "zoneCode": "MO", + "zoneName": "Missouri", + "countryCode": "US" + }, + { + "zoneCode": "MT", + "zoneName": "Montana", + "countryCode": "US" + }, + { + "zoneCode": "NE", + "zoneName": "Nebraska", + "countryCode": "US" + }, + { + "zoneCode": "NV", + "zoneName": "Nevada", + "countryCode": "US" + }, + { + "zoneCode": "NH", + "zoneName": "New Hampshire", + "countryCode": "US" + }, + { + "zoneCode": "NJ", + "zoneName": "New Jersey", + "countryCode": "US" + }, + { + "zoneCode": "NM", + "zoneName": "New Mexico", + "countryCode": "US" + }, + { + "zoneCode": "NY", + "zoneName": "New York", + "countryCode": "US" + }, + { + "zoneCode": "NC", + "zoneName": "North Carolina", + "countryCode": "US" + }, + { + "zoneCode": "ND", + "zoneName": "North Dakota", + "countryCode": "US" + }, + { + "zoneCode": "MP", + "zoneName": "Northern Mariana Islands", + "countryCode": "US" + }, + { + "zoneCode": "OH", + "zoneName": "Ohio", + "countryCode": "US" + }, + { + "zoneCode": "OK", + "zoneName": "Oklahoma", + "countryCode": "US" + }, + { + "zoneCode": "OR", + "zoneName": "Oregon", + "countryCode": "US" + }, + { + "zoneCode": "PA", + "zoneName": "Pennsylvania", + "countryCode": "US" + }, + { + "zoneCode": "PR", + "zoneName": "Puerto Rico", + "countryCode": "US" + }, + { + "zoneCode": "RI", + "zoneName": "Rhode Island", + "countryCode": "US" + }, + { + "zoneCode": "SC", + "zoneName": "South Carolina", + "countryCode": "US" + }, + { + "zoneCode": "SD", + "zoneName": "South Dakota", + "countryCode": "US" + }, + { + "zoneCode": "TN", + "zoneName": "Tennessee", + "countryCode": "US" + }, + { + "zoneCode": "TX", + "zoneName": "Texas", + "countryCode": "US" + }, + { + "zoneCode": "UT", + "zoneName": "Utah", + "countryCode": "US" + }, + { + "zoneCode": "VT", + "zoneName": "Vermont", + "countryCode": "US" + }, + { + "zoneCode": "VI", + "zoneName": "Virgin Islands", + "countryCode": "US" + }, + { + "zoneCode": "VA", + "zoneName": "Virginia", + "countryCode": "US" + }, + { + "zoneCode": "WA", + "zoneName": "Washington", + "countryCode": "US" + }, + { + "zoneCode": "WV", + "zoneName": "West Virginia", + "countryCode": "US" + }, + { + "zoneCode": "WI", + "zoneName": "Wisconsin", + "countryCode": "US" + }, + { + "zoneCode": "WY", + "zoneName": "Wyoming", + "countryCode": "US" + }, + { + "zoneCode": "AB", + "zoneName": "Alberta", + "countryCode": "CA" + }, + { + "zoneCode": "BC", + "zoneName": "British Columbia", + "countryCode": "CA" + }, + { + "zoneCode": "MB", + "zoneName": "Manitoba", + "countryCode": "CA" + }, + { + "zoneCode": "NF", + "zoneName": "Newfoundland - Labrador", + "countryCode": "CA" + }, + { + "zoneCode": "NB", + "zoneName": "New Brunswick", + "countryCode": "CA" + }, + { + "zoneCode": "NS", + "zoneName": "Nova Scotia", + "countryCode": "CA" + }, + { + "zoneCode": "NT", + "zoneName": "Northwest Territories", + "countryCode": "CA" + }, + { + "zoneCode": "NU", + "zoneName": "Nunavut", + "countryCode": "CA" + }, + { + "zoneCode": "ON", + "zoneName": "Ontario", + "countryCode": "CA" + }, + { + "zoneCode": "PE", + "zoneName": "Prince Edward Island", + "countryCode": "CA" + }, + { + "zoneCode": "QC", + "zoneName": "Quebec", + "countryCode": "CA" + }, + { + "zoneCode": "SK", + "zoneName": "Saskatchewan", + "countryCode": "CA" + }, + { + "zoneCode": "YT", + "zoneName": "Yukon Territory", + "countryCode": "CA" + }, + { + "zoneCode": "NDS", + "zoneName": "Niedersachsen", + "countryCode": "DE" + }, + { + "zoneCode": "BAW", + "zoneName": "Baden-Wrttemberg", + "countryCode": "DE" + }, + { + "zoneCode": "BAY", + "zoneName": "Bayern", + "countryCode": "DE" + }, + { + "zoneCode": "BER", + "zoneName": "Berlin", + "countryCode": "DE" + }, + { + "zoneCode": "BRG", + "zoneName": "Brandenburg", + "countryCode": "DE" + }, + { + "zoneCode": "BRE", + "zoneName": "Bremen", + "countryCode": "DE" + }, + { + "zoneCode": "HAM", + "zoneName": "Hamburg", + "countryCode": "DE" + }, + { + "zoneCode": "HES", + "zoneName": "Hessen", + "countryCode": "DE" + }, + { + "zoneCode": "MEC", + "zoneName": "Mecklenburg-Vorpommern", + "countryCode": "DE" + }, + { + "zoneCode": "NRW", + "zoneName": "Nordrhein-Westfalen", + "countryCode": "DE" + }, + { + "zoneCode": "RHE", + "zoneName": "Rheinland-Pfalz", + "countryCode": "DE" + }, + { + "zoneCode": "SAR", + "zoneName": "Saarland", + "countryCode": "DE" + }, + { + "zoneCode": "SAS", + "zoneName": "Sachsen", + "countryCode": "DE" + }, + { + "zoneCode": "SAC", + "zoneName": "Sachsen-Anhalt", + "countryCode": "DE" + }, + { + "zoneCode": "SCN", + "zoneName": "Schleswig-Holstein", + "countryCode": "DE" + }, + { + "zoneCode": "THE", + "zoneName": "Thringen", + "countryCode": "DE" + }, + { + "zoneCode": "WIAT", + "zoneName": "Wien", + "countryCode": "AT" + }, + { + "zoneCode": "NO", + "zoneName": "Niederosterreich", + "countryCode": "AT" + }, + { + "zoneCode": "OO", + "zoneName": "Oberosterreich", + "countryCode": "AT" + }, + { + "zoneCode": "SB", + "zoneName": "Salzburg", + "countryCode": "AT" + }, + { + "zoneCode": "KN", + "zoneName": "Katen", + "countryCode": "AT" + }, + { + "zoneCode": "ST", + "zoneName": "Steiermark", + "countryCode": "AT" + }, + { + "zoneCode": "TIAT", + "zoneName": "Tirol", + "countryCode": "AT" + }, + { + "zoneCode": "BLAT", + "zoneName": "Burgenland", + "countryCode": "AT" + }, + { + "zoneCode": "VB", + "zoneName": "Voralberg", + "countryCode": "AT" + }, + { + "zoneCode": "AG", + "zoneName": "Aargau", + "countryCode": "CH" + }, + { + "zoneCode": "AI", + "zoneName": "Appenzell Innerrhoden", + "countryCode": "CH" + }, + { + "zoneCode": "ARCH", + "zoneName": "Appenzell Ausserrhoden", + "countryCode": "CH" + }, + { + "zoneCode": "BE", + "zoneName": "Bern", + "countryCode": "CH" + }, + { + "zoneCode": "BL", + "zoneName": "Basel-Landschaft", + "countryCode": "CH" + }, + { + "zoneCode": "BS", + "zoneName": "Basel-Stadt", + "countryCode": "CH" + }, + { + "zoneCode": "FR", + "zoneName": "Freiburg", + "countryCode": "CH" + }, + { + "zoneCode": "GE", + "zoneName": "Genf", + "countryCode": "CH" + }, + { + "zoneCode": "GL", + "zoneName": "Glarus", + "countryCode": "CH" + }, + { + "zoneCode": "GR", + "zoneName": "Graubnden", + "countryCode": "CH" + }, + { + "zoneCode": "JU", + "zoneName": "Jura", + "countryCode": "CH" + }, + { + "zoneCode": "LU", + "zoneName": "Luzern", + "countryCode": "CH" + }, + { + "zoneCode": "NECH", + "zoneName": "Neuenburg", + "countryCode": "CH" + }, + { + "zoneCode": "NW", + "zoneName": "Nidwalden", + "countryCode": "CH" + }, + { + "zoneCode": "OW", + "zoneName": "Obwalden", + "countryCode": "CH" + }, + { + "zoneCode": "SG", + "zoneName": "St. Gallen", + "countryCode": "CH" + }, + { + "zoneCode": "SH", + "zoneName": "Schaffhausen", + "countryCode": "CH" + }, + { + "zoneCode": "SO", + "zoneName": "Solothurn", + "countryCode": "CH" + }, + { + "zoneCode": "SZ", + "zoneName": "Schwyz", + "countryCode": "CH" + }, + { + "zoneCode": "TG", + "zoneName": "Thurgau", + "countryCode": "CH" + }, + { + "zoneCode": "TI", + "zoneName": "Tessin", + "countryCode": "CH" + }, + { + "zoneCode": "UR", + "zoneName": "Uri", + "countryCode": "CH" + }, + { + "zoneCode": "VD", + "zoneName": "Waadt", + "countryCode": "CH" + }, + { + "zoneCode": "VS", + "zoneName": "Wallis", + "countryCode": "CH" + }, + { + "zoneCode": "ZG", + "zoneName": "Zug", + "countryCode": "CH" + }, + { + "zoneCode": "ZH", + "zoneName": "Zrich", + "countryCode": "CH" + }, + { + "zoneCode": "ACorua", + "zoneName": "A Corua", + "countryCode": "ES" + }, + { + "zoneCode": "Alava", + "zoneName": "Alava", + "countryCode": "ES" + }, + { + "zoneCode": "Albacete", + "zoneName": "Albacete", + "countryCode": "ES" + }, + { + "zoneCode": "Alicante", + "zoneName": "Alicante", + "countryCode": "ES" + }, + { + "zoneCode": "Almeria", + "zoneName": "Almeria", + "countryCode": "ES" + }, + { + "zoneCode": "Asturias", + "zoneName": "Asturias", + "countryCode": "ES" + }, + { + "zoneCode": "Avila", + "zoneName": "Avila", + "countryCode": "ES" + }, + { + "zoneCode": "Badajoz", + "zoneName": "Badajoz", + "countryCode": "ES" + }, + { + "zoneCode": "Baleares", + "zoneName": "Baleares", + "countryCode": "ES" + }, + { + "zoneCode": "Barcelona", + "zoneName": "Barcelona", + "countryCode": "ES" + }, + { + "zoneCode": "Burgos", + "zoneName": "Burgos", + "countryCode": "ES" + }, + { + "zoneCode": "Caceres", + "zoneName": "Caceres", + "countryCode": "ES" + }, + { + "zoneCode": "Cadiz", + "zoneName": "Cadiz", + "countryCode": "ES" + }, + { + "zoneCode": "Cantabria", + "zoneName": "Cantabria", + "countryCode": "ES" + }, + { + "zoneCode": "Castellon", + "zoneName": "Castellon", + "countryCode": "ES" + }, + { + "zoneCode": "Ceuta", + "zoneName": "Ceuta", + "countryCode": "ES" + }, + { + "zoneCode": "CiudadReal", + "zoneName": "Ciudad Real", + "countryCode": "ES" + }, + { + "zoneCode": "Cordoba", + "zoneName": "Cordoba", + "countryCode": "ES" + }, + { + "zoneCode": "Cuenca", + "zoneName": "Cuenca", + "countryCode": "ES" + }, + { + "zoneCode": "Girona", + "zoneName": "Girona", + "countryCode": "ES" + }, + { + "zoneCode": "Granada", + "zoneName": "Granada", + "countryCode": "ES" + }, + { + "zoneCode": "Guadalajara", + "zoneName": "Guadalajara", + "countryCode": "ES" + }, + { + "zoneCode": "Guipuzcoa", + "zoneName": "Guipuzcoa", + "countryCode": "ES" + }, + { + "zoneCode": "Huelva", + "zoneName": "Huelva", + "countryCode": "ES" + }, + { + "zoneCode": "Huesca", + "zoneName": "Huesca", + "countryCode": "ES" + }, + { + "zoneCode": "Jaen", + "zoneName": "Jaen", + "countryCode": "ES" + }, + { + "zoneCode": "LaRioja", + "zoneName": "La Rioja", + "countryCode": "ES" + }, + { + "zoneCode": "LasPalmas", + "zoneName": "Las Palmas", + "countryCode": "ES" + }, + { + "zoneCode": "Leon", + "zoneName": "Leon", + "countryCode": "ES" + }, + { + "zoneCode": "Lleida", + "zoneName": "Lleida", + "countryCode": "ES" + }, + { + "zoneCode": "Lugo", + "zoneName": "Lugo", + "countryCode": "ES" + }, + { + "zoneCode": "Madrid", + "zoneName": "Madrid", + "countryCode": "ES" + }, + { + "zoneCode": "Malaga", + "zoneName": "Malaga", + "countryCode": "ES" + }, + { + "zoneCode": "Melilla", + "zoneName": "Melilla", + "countryCode": "ES" + }, + { + "zoneCode": "Murcia", + "zoneName": "Murcia", + "countryCode": "ES" + }, + { + "zoneCode": "Navarra", + "zoneName": "Navarra", + "countryCode": "ES" + }, + { + "zoneCode": "Ourense", + "zoneName": "Ourense", + "countryCode": "ES" + }, + { + "zoneCode": "Palencia", + "zoneName": "Palencia", + "countryCode": "ES" + }, + { + "zoneCode": "Pontevedra", + "zoneName": "Pontevedra", + "countryCode": "ES" + }, + { + "zoneCode": "Salamanca", + "zoneName": "Salamanca", + "countryCode": "ES" + }, + { + "zoneCode": "SantaCruzdeTenerife", + "zoneName": "Santa Cruz de Tenerife", + "countryCode": "ES" + }, + { + "zoneCode": "Segovia", + "zoneName": "Segovia", + "countryCode": "ES" + }, + { + "zoneCode": "Sevilla", + "zoneName": "Sevilla", + "countryCode": "ES" + }, + { + "zoneCode": "Soria", + "zoneName": "Soria", + "countryCode": "ES" + }, + { + "zoneCode": "Tarragona", + "zoneName": "Tarragona", + "countryCode": "ES" + }, + { + "zoneCode": "Teruel", + "zoneName": "Teruel", + "countryCode": "ES" + }, + { + "zoneCode": "Toledo", + "zoneName": "Toledo", + "countryCode": "ES" + }, + { + "zoneCode": "Valencia", + "zoneName": "Valencia", + "countryCode": "ES" + }, + { + "zoneCode": "Valladolid", + "zoneName": "Valladolid", + "countryCode": "ES" + }, + { + "zoneCode": "Vizcaya", + "zoneName": "Vizcaya", + "countryCode": "ES" + }, + { + "zoneCode": "Zamora", + "zoneName": "Zamora", + "countryCode": "ES" + }, + { + "zoneCode": "Zaragoza", + "zoneName": "Zaragoza", + "countryCode": "ES" + }, + { + "zoneCode": "ACT", + "zoneName": "Australian Capital Territory", + "countryCode": "AU" + }, + { + "zoneCode": "NSW", + "zoneName": "New South Wales", + "countryCode": "AU" + }, + { + "zoneCode": "NTAU", + "zoneName": "Northern Territory", + "countryCode": "AU" + }, + { + "zoneCode": "QLD", + "zoneName": "Queensland", + "countryCode": "AU" + }, + { + "zoneCode": "SA", + "zoneName": "South Australia", + "countryCode": "AU" + }, + { + "zoneCode": "TAS", + "zoneName": "Tasmania", + "countryCode": "AU" + }, + { + "zoneCode": "VIC", + "zoneName": "Victoria", + "countryCode": "AU" + }, + { + "zoneCode": "WAAU", + "zoneName": "Western Australia", + "countryCode": "AU" + }, + { + "zoneCode": "ASU", + "zoneName": "Asunción", + "countryCode": "PY" + }, + { + "zoneCode": "CEN", + "zoneName": "Central", + "countryCode": "PY" + }, + { + "zoneCode": "OTR", + "zoneName": "Otro", + "countryCode": "PY" + } +] +} diff --git a/sm-core/src/main/resources/reference/zones/in.json b/sm-core/src/main/resources/reference/zones/in.json new file mode 100755 index 0000000000..53644728bc --- /dev/null +++ b/sm-core/src/main/resources/reference/zones/in.json @@ -0,0 +1,140 @@ +{ + "*":[ + { + "zoneCode": "AndhraPradesh", + "zoneName": "Andhra Pradesh", + "countryCode": "IN" + }, + { + "zoneCode": "ArunachalPradesh", + "zoneName": "Arunachal Pradesh", + "countryCode": "IN" + }, + { + "zoneCode": "Assam", + "zoneName": "Assam", + "countryCode": "IN" + }, + { + "zoneCode": "Bihar", + "zoneName": "Bihar", + "countryCode": "IN" + }, + { + "zoneCode": "Chhattisgarh", + "zoneName": "Chhattisgarh", + "countryCode": "IN" + }, + { + "zoneCode": "Goa", + "zoneName": "Goa", + "countryCode": "IN" + }, + { + "zoneCode": "Gujarat", + "zoneName": "Gujarat", + "countryCode": "IN" + }, + { + "zoneCode": "Haryana", + "zoneName": "Haryana", + "countryCode": "IN" + }, + { + "zoneCode": "HimachalPradesh", + "zoneName": "Himachal Pradesh", + "countryCode": "IN" + }, + { + "zoneCode": "Jharkhand", + "zoneName": "Jharkhand", + "countryCode": "IN" + }, + { + "zoneCode": "Karnataka", + "zoneName": "Karnataka", + "countryCode": "IN" + }, + { + "zoneCode": "Kerala", + "zoneName": "Kerala", + "countryCode": "IN" + }, + { + "zoneCode": "MadhyaPradesh", + "zoneName": "Madhya Pradesh", + "countryCode": "IN" + }, + { + "zoneCode": "Maharashtra", + "zoneName": "Maharashtra", + "countryCode": "IN" + }, + { + "zoneCode": "Manipur", + "zoneName": "Manipur", + "countryCode": "IN" + }, + { + "zoneCode": "Meghalaya", + "zoneName": "Meghalaya", + "countryCode": "IN" + }, + { + "zoneCode": "Mizoram", + "zoneName": "Mizoram", + "countryCode": "IN" + }, + { + "zoneCode": "Nagaland", + "zoneName": "Nagaland", + "countryCode": "IN" + }, + { + "zoneCode": "Odisha", + "zoneName": "Odisha", + "countryCode": "IN" + }, + { + "zoneCode": "Punjab", + "zoneName": "Punjab", + "countryCode": "IN" + }, + { + "zoneCode": "Rajasthan", + "zoneName": "Rajasthan", + "countryCode": "IN" + }, + { + "zoneCode": "Sikkim", + "zoneName": "Sikkim", + "countryCode": "IN" + }, + { + "zoneCode": "TamilNadu", + "zoneName": "Tamil Nadu", + "countryCode": "IN" + }, + { + "zoneCode": "Telangana", + "zoneName": "Telangana", + "countryCode": "IN" + }, + { + "zoneCode": "Tripura", + "zoneName": "Tripura", + "countryCode": "IN" + }, + { + "zoneCode": "Uttarakhand", + "zoneName": "Uttarakhand", + "countryCode": "IN" + }, + { + "zoneCode": "WestBengal", + "zoneName": "West Bengal", + "countryCode": "IN" + } + + ] +} diff --git a/sm-core/src/main/resources/rules/manufacturer-shipping-ordertotal-rules.xls b/sm-core/src/main/resources/rules/manufacturer-shipping-ordertotal-rules.xls new file mode 100755 index 0000000000..3cabd49c5e Binary files /dev/null and b/sm-core/src/main/resources/rules/manufacturer-shipping-ordertotal-rules.xls differ diff --git a/sm-core/src/main/resources/search/MAPPINGS.json b/sm-core/src/main/resources/search/MAPPINGS.json new file mode 100644 index 0000000000..c57bf21ad5 --- /dev/null +++ b/sm-core/src/main/resources/search/MAPPINGS.json @@ -0,0 +1,53 @@ +{ + "properties": { + "id": { + "type": "long" + }, + "inventory": { + "type": "nested" + }, + "description": { + "type": "text" + }, + "name": { + "type": "text", + "analyzer": "name_analyzer" + }, + "category": { + "type": "keyword", + "normalizer": "custom_normalizer", + "fields": { + "raw": { + "type": "text" + } + } + }, + "brand": { + "type": "keyword", + "normalizer": "custom_normalizer", + "fields": { + "raw": { + "type": "text" + } + } + }, + "attributes": { + "type": "nested" + }, + "variants": { + "type": "nested" + }, + "store": { + "type": "keyword" + }, + "link": { + "type": "keyword" + }, + "reviews": { + "type": "keyword" + }, + "image": { + "type": "keyword" + } + } +} \ No newline at end of file diff --git a/sm-core/src/main/resources/search/SETTINGS_DEFAULT.json b/sm-core/src/main/resources/search/SETTINGS_DEFAULT.json new file mode 100644 index 0000000000..37317bbaf0 --- /dev/null +++ b/sm-core/src/main/resources/search/SETTINGS_DEFAULT.json @@ -0,0 +1,28 @@ +{ + "analysis": { + "analyzer": { + "name_analyzer": { + "tokenizer": "name_tokenizer", + "filter": [ "lowercase" ] + } + }, + "tokenizer": { + "name_tokenizer": { + "type": "edge_ngram", + "min_gram": 3, + "max_gram": 10, + "token_chars": [ + "letter", + "digit" + ] + } + }, + "normalizer": { + "custom_normalizer": { + "type": "custom", + "char_filter": [], + "filter": ["lowercase", "asciifolding"] + } + } + } +} \ No newline at end of file diff --git a/sm-core/src/main/resources/search/SETTINGS_en.json b/sm-core/src/main/resources/search/SETTINGS_en.json new file mode 100644 index 0000000000..37317bbaf0 --- /dev/null +++ b/sm-core/src/main/resources/search/SETTINGS_en.json @@ -0,0 +1,28 @@ +{ + "analysis": { + "analyzer": { + "name_analyzer": { + "tokenizer": "name_tokenizer", + "filter": [ "lowercase" ] + } + }, + "tokenizer": { + "name_tokenizer": { + "type": "edge_ngram", + "min_gram": 3, + "max_gram": 10, + "token_chars": [ + "letter", + "digit" + ] + } + }, + "normalizer": { + "custom_normalizer": { + "type": "custom", + "char_filter": [], + "filter": ["lowercase", "asciifolding"] + } + } + } +} \ No newline at end of file diff --git a/sm-core/src/main/resources/shopizer-core.properties b/sm-core/src/main/resources/shopizer-core.properties new file mode 100755 index 0000000000..fc670b4211 --- /dev/null +++ b/sm-core/src/main/resources/shopizer-core.properties @@ -0,0 +1,111 @@ +#Must be 16 digits (replace with your own creation !) +secretKey=7070200000000007 + + +#Deprecated in favor of search starter +#Elastic Search configurations +elasticsearch.cluster.name=shopizer +elasticsearch.mode=remote +#coma seperated host values +elasticsearch.server.host=localhost +elasticsearch.server.protocole=http +elasticsearch.server.port=9200 +elasticsearch.server.proxy.user= +elasticsearch.server.proxy.password= +#enable if ES is secured (by default it is not) +elasticsearch.security.enabled=false +elasticsearch.security.user=elastic +elasticsearch.security.password=changeme + +###Search starter configuration instead of config above +search.credentials.username=admin +search.credentials.password=admin + +search.clusterName=opensearch-cluster +#search.jksAbsolutePath=/Users/csa/Documents/dev/processes/open-search/config/testnode.jks +search.jksAbsolutePath= + +#Languages to be configured for the search engine. Too much will impact the size and how indexes are built +search.searchLanguages=en,fr + +search.host[0].scheme=http +search.host[0].host=0.0.0.0 +search.host[0].port=9200 +search.host[1].scheme=http +search.host[1].host=0.0.0.0 +search.host[1].port=9201 + +#do not index in default profile +search.noindex=true + +# Which CMS method to use [ default | httpd | aws | gcp ] +# default = infinispan +# httpd = requires http server +# aws = AWS S3 -> See AWS S3 configuration below +# gcp = Google Cloud Storage + +config.cms.method=default +config.cms.contentUrl=http://localhost:8080 +config.cms.static.path=/static + + +#Infinispan configuration +#Specifies where files are located +config.cms.store.location=./files/store +config.cms.files.location=./files/repos + +#httpd configuration +#Specifies where htdocs repository is located +config.cms.http.path.location= + + +#AWS S3 configuration +#Name of bucket files +#See regions here https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html +#Credentials must be set as environment variables when launching Shopizer +#AWS_ACCESS_KEY_ID= +#AWS_SECRETE_ACCESS_KEY= +config.cms.aws.bucket= +config.cms.aws.region=us-east-1 + +#GCP Cloud Storage configuration +#Name of the bucket file +#If the bucket does not exists it will be created +#export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/[FILE_NAME].json" +config.cms.gcp.bucket= + +#You need an AWS access key ID and AWS secret access key to access Amazon SES using an SDK +#AWS keys need to be specified in environment variables +# -e AWS_ACCESS_KEY_ID=YOUR-ACCESS-KEY \ +# -e AWS_SECRET_ACCESS_KEY=YOUR-SECRET-ACCESS-KEY \ +#Email implementation [default | ses] +#default=SpringHtmlEmailSender - through SMTP server and requires configurations from admin console +#ses=AWS SES service +config.emailSender=default +config.emailSender.region=US_EAST_1 + +#Shipping activated in the system ? +config.displayShipping=true + +#Google map API key +#For using priceByDistance shipping module +#See shopizer-core-modules.xml +config.shippingDistancePreProcessor.apiKey= +config.shippingDistancePreProcessor.acceptedZones=QC,ON,AB,NY,MA + +#checkout and signup address validation +#see : https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete-addressform +#Should be passed as an environment key +config.googleMapsKey= + +#recaptcha https://developers.google.com/recaptcha/ +#testing keys +config.recaptcha.secretKey=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe +config.recaptcha.siteKey=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI + +#shipping rules +config.shipping.rule.priceByDistance=PriceByDistance.drl +config.shipping.rule.shippingModuleDecision=ShippingDecision.drl + +#Creates default database data (should always be true) +db.init.data=true diff --git a/sm-core/src/main/resources/spring/ehcache.xml b/sm-core/src/main/resources/spring/ehcache.xml new file mode 100755 index 0000000000..e353330109 --- /dev/null +++ b/sm-core/src/main/resources/spring/ehcache.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sm-core/src/main/resources/spring/processors/shopizer-core-ordertotal-processors.xml b/sm-core/src/main/resources/spring/processors/shopizer-core-ordertotal-processors.xml new file mode 100755 index 0000000000..c20585b5ca --- /dev/null +++ b/sm-core/src/main/resources/spring/processors/shopizer-core-ordertotal-processors.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/sm-core/src/main/resources/spring/processors/shopizer-core-shipping-processors.xml b/sm-core/src/main/resources/spring/processors/shopizer-core-shipping-processors.xml new file mode 100755 index 0000000000..8d7ca5bcb2 --- /dev/null +++ b/sm-core/src/main/resources/spring/processors/shopizer-core-shipping-processors.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sm-core/src/main/resources/spring/shopizer-core-cms.xml b/sm-core/src/main/resources/spring/shopizer-core-cms.xml new file mode 100755 index 0000000000..3f5873b191 --- /dev/null +++ b/sm-core/src/main/resources/spring/shopizer-core-cms.xml @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sm-core/src/main/resources/spring/shopizer-core-config.xml b/sm-core/src/main/resources/spring/shopizer-core-config.xml new file mode 100755 index 0000000000..356759660d --- /dev/null +++ b/sm-core/src/main/resources/spring/shopizer-core-config.xml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + classpath:email.properties + classpath:shopizer-core.properties + classpath:authentication.properties + + + + + + + + + + + classpath:database.properties + classpath:email.properties + classpath:shopizer-core.properties + classpath:authentication.properties + + + + + + + + + + + classpath:profiles/gcp/database.properties + classpath:email.properties + classpath:profiles/gcp/shopizer-core.properties + + classpath:authentication.properties + + + + + + + + + + + classpath:profiles/cloud/database.properties + classpath:email.properties + classpath:profiles/cloud/shopizer-core.properties + + classpath:authentication.properties + + + + + + + + + + + classpath:profiles/local/database.properties + classpath:email.properties + classpath:profiles/local/shopizer-core.properties + classpath:authentication.properties + + + + + + + + + + + classpath:profiles/mysql/database.properties + classpath:email.properties + classpath:profiles/mysql/shopizer-core.properties + classpath:authentication.properties + + + + + \ No newline at end of file diff --git a/sm-core/src/main/resources/spring/shopizer-core-context.xml b/sm-core/src/main/resources/spring/shopizer-core-context.xml new file mode 100755 index 0000000000..ad9a75d09c --- /dev/null +++ b/sm-core/src/main/resources/spring/shopizer-core-context.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sm-core/src/main/resources/spring/shopizer-core-ehcache.xml b/sm-core/src/main/resources/spring/shopizer-core-ehcache.xml new file mode 100755 index 0000000000..9f676b2d57 --- /dev/null +++ b/sm-core/src/main/resources/spring/shopizer-core-ehcache.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sm-core/src/main/resources/spring/shopizer-core-modules.xml b/sm-core/src/main/resources/spring/shopizer-core-modules.xml new file mode 100755 index 0000000000..78996d888c --- /dev/null +++ b/sm-core/src/main/resources/spring/shopizer-core-modules.xml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${mailSender.username} + + + + ${mailSender.password} + + + + + ${mailSender.mail.smtp.auth} + ${mail.smtp.starttls.enable} + + + + + + + \ No newline at end of file diff --git a/sm-core/src/main/resources/templates/email/email_template_checkout.ftl b/sm-core/src/main/resources/templates/email/email_template_checkout.ftl new file mode 100755 index 0000000000..dbe0a62776 --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_checkout.ftl @@ -0,0 +1,417 @@ + + + + + + + + + + + + + + + + + + + + + + +
    + +

    + + + + +
    + ${LOGOPATH} +
    +

    + +
    + + + + + + + + + + + + + + + + + + +
    +
    + + + + +
    +

    ${LABEL_HI} ${EMAIL_CUSTOMER_FIRSTNAME} ${EMAIL_CUSTOMER_LASTNAME}

    +

    + ${EMAIL_ORDER_NUMBER} +

    +
    +

    + ${EMAIL_ORDER_DATE}
    + ${EMAIL_ORDER_THANKS} +

    +
    +
    +
    + + +

    +

    ${EMAIL_ORDER_DETAILS_TITLE}

    +

    +

    + ${ORDER_PRODUCTS_DETAILS} +

    +
    + + + + + + + + + + +
    + + + +
    + + + +
    +
    + +
    + + + + + + + +
    +
    + +

    + ${ORDER_STATUS} +

    +
    +
    + + + + + + + + + + + + + + + + diff --git a/sm-core/src/main/resources/templates/email/email_template_checkout_download.ftl b/sm-core/src/main/resources/templates/email/email_template_checkout_download.ftl new file mode 100755 index 0000000000..69de9d4ca6 --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_checkout_download.ftl @@ -0,0 +1,329 @@ + + + + + + + + + + + + + + + + + + + + + +
    + +

    + + + + +
    +

    ${LOGOPATH}

    +
    +

    + +
    + + + + + + + + + + +
    + +
    + + + + +
    +

    ${LABEL_HI} ${EMAIL_CUSTOMER_FIRSTNAME} ${EMAIL_CUSTOMER_LASTNAME}

    +

    + ${EMAIL_ORDER_DOWNLOAD} +

    + +

    + ${CUSTOMER_ACCESS_LABEL} ${ACCESS_NOW_LABEL} » +

    + + +
    +
    + +
    + + + + + + + + + + + + diff --git a/sm-core/src/main/resources/templates/email/email_template_contact.ftl b/sm-core/src/main/resources/templates/email/email_template_contact.ftl new file mode 100755 index 0000000000..51c5a90ce9 --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_contact.ftl @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + +
    + +

    + + + + +
    +

    ${LOGOPATH}

    +
    +

    + +
    + + + + + + + + + + +
    + +
    + + + + +
    +

    + ${EMAIL_CUSTOMER_CONTACT} +

    +

    + ${EMAIL_CONTACT_NAME_LABEL}: ${EMAIL_CONTACT_NAME}
    + ${EMAIL_CONTACT_EMAIL_LABEL}: ${EMAIL_CONTACT_EMAIL}
    + +

    + +

    + ${EMAIL_CONTACT_CONTENT} +

    + + +
    +
    + +
    + + + + + + + + + + + + diff --git a/sm-core/src/main/resources/templates/email/email_template_customer.ftl b/sm-core/src/main/resources/templates/email/email_template_customer.ftl new file mode 100755 index 0000000000..6ec616b618 --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_customer.ftl @@ -0,0 +1,334 @@ + + + + + + + + + + + + + + + + + + + + + +
    + +

    + + + + +
    +

    ${LOGOPATH}

    +
    +

    + +
    + + + + + + + + + + +
    + +
    + + + + +
    +

    ${LABEL_HI} ${EMAIL_CUSTOMER_FIRSTNAME} ${EMAIL_CUSTOMER_LASTNAME}

    +

    + ${EMAIL_CUSTOMER_GREETING} +

    +

    + ${EMAIL_USERNAME_LABEL}: ${EMAIL_USER_NAME}
    + ${EMAIL_PASSWORD_LABEL}: ${EMAIL_CUSTOMER_PASSWORD}
    + +

    + +

    + ${CUSTOMER_ACCESS_LABEL} ${ACCESS_NOW_LABEL} » +

    + + +
    +
    + +
    + + + + + + + + + + + + diff --git a/sm-core/src/main/resources/templates/email/email_template_customer_confirm_emil.ftl b/sm-core/src/main/resources/templates/email/email_template_customer_confirm_emil.ftl new file mode 100755 index 0000000000..6ec616b618 --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_customer_confirm_emil.ftl @@ -0,0 +1,334 @@ + + + + + + + + + + + + + + + + + + + + + +
    + +

    + + + + +
    +

    ${LOGOPATH}

    +
    +

    + +
    + + + + + + + + + + +
    + +
    + + + + +
    +

    ${LABEL_HI} ${EMAIL_CUSTOMER_FIRSTNAME} ${EMAIL_CUSTOMER_LASTNAME}

    +

    + ${EMAIL_CUSTOMER_GREETING} +

    +

    + ${EMAIL_USERNAME_LABEL}: ${EMAIL_USER_NAME}
    + ${EMAIL_PASSWORD_LABEL}: ${EMAIL_CUSTOMER_PASSWORD}
    + +

    + +

    + ${CUSTOMER_ACCESS_LABEL} ${ACCESS_NOW_LABEL} » +

    + + +
    +
    + +
    + + + + + + + + + + + + diff --git a/sm-core/src/main/resources/templates/email/email_template_lowstock.ftl b/sm-core/src/main/resources/templates/email/email_template_lowstock.ftl new file mode 100755 index 0000000000..0970e7725c --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_lowstock.ftl @@ -0,0 +1,50 @@ + + + + + + + + + + + +
    + + + +
    +
    + ${EMAIL_STORE_NAME}

    + ${EMAIL_PRODUCT_TEXT}
    +
    +
    + +
    + + + + +
    +
    ${EMAIL_DISCLAIMER}
    +
    ${EMAIL_SPAM_DISCLAIMER}
    +
    + + diff --git a/sm-core/src/main/resources/templates/email/email_template_marketing.ftl b/sm-core/src/main/resources/templates/email/email_template_marketing.ftl new file mode 100755 index 0000000000..cad06d7f54 --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_marketing.ftl @@ -0,0 +1,372 @@ + + + + + + + + + + + Merry Christmas from BAM Wood + + + + + + + + + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + Please enable images to view this content +
    + BAM Wood wanted to drop in and say Merry Christmas and Hapy Hollidays to you and your family. +
    + We hope your days be filled with love, laughter and lots of amazing surprizes. +
    + We feel blessed to have had the opportunity to work with you in 2020 and can't wait to share with you what we have prepared for 2021! +
    + Many blessing to you and yours - BAM Wood team +

    +
    + Have a question? info@bamwood.ca +
    + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + Please enable images to view this content +
    + BAM Wood vous souhaite de Joyeuses fêtes à vous ainsi qu'a votre famille. +
    + Que cette période soit remplie d'amour, de rires et de nombreuses surprises. +
    + Nous avons eu la chance de travailler ensemble en 2020 et nous avons hâte de vous présenter ce que nous avons préparé pour 2021! +
    + Que nos vœux de bonheur vous accompagnent
    L'équipe BAM Wood +

    +
    + Pour répondre à vos questions info@bamwood.ca +
    + + + + + + + + + + + + + + + + +
    + + + + + + + + \ No newline at end of file diff --git a/sm-core/src/main/resources/templates/email/email_template_new_review.ftl b/sm-core/src/main/resources/templates/email/email_template_new_review.ftl new file mode 100755 index 0000000000..747a7b20a0 --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_new_review.ftl @@ -0,0 +1,52 @@ + + + + + + + + + + +
    + + + +
    +
    + ${EMAIL_STORE_NAME}


    + ${EMAIL_SUBJECT} - ${EMAIL_PRODUCT_NAME}
    + ${EMAIL_CUSTOMER_REVIEW}

    + ${EMAIL_REVIEW_RATING}

    + ${EMAIL_REVIEW_TEXT}
    +
    +
    + +
    + + + + +
    +
    ${EMAIL_DISCLAIMER}
    +
    ${EMAIL_SPAM_DISCLAIMER}
    +
    + + diff --git a/sm-core/src/main/resources/templates/email/email_template_new_store.ftl b/sm-core/src/main/resources/templates/email/email_template_new_store.ftl new file mode 100755 index 0000000000..c2b51d4539 --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_new_store.ftl @@ -0,0 +1,50 @@ + + + + + + + + + + +
    + + +
    +
    + ${EMAIL_NEW_STORE_TEXT}


    + ${EMAIL_STORE_NAME}

    + ${EMAIL_ADMIN_STORE_INFO_LABEL}
    + ${EMAIL_ADMIN_URL_LABEL}

    +
    +
    + +
    + + + + +
    +
    ${EMAIL_DISCLAIMER}
    +
    ${EMAIL_SPAM_DISCLAIMER}
    +
    + + diff --git a/sm-core/src/main/resources/templates/email/email_template_new_user.ftl b/sm-core/src/main/resources/templates/email/email_template_new_user.ftl new file mode 100755 index 0000000000..4a3f192723 --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_new_user.ftl @@ -0,0 +1,52 @@ + + + + + + + + + + +
    + + +
    +
    + ${EMAIL_NEW_USER_TEXT}

    + ${EMAIL_STORE_NAME}

    + ${EMAIL_TEXT_NEW_USER_CREATED}
    + ${EMAIL_ADMIN_USERNAME_LABEL}: ${EMAIL_ADMIN_NAME}
    + ${EMAIL_ADMIN_PASSWORD_LABEL}: ${EMAIL_ADMIN_PASSWORD}
    + ${EMAIL_ADMIN_URL_LABEL}: ${EMAIL_ADMIN_URL}

    +
    +
    + +
    + + + + +
    +
    ${EMAIL_DISCLAIMER}
    +
    ${EMAIL_SPAM_DISCLAIMER}
    +
    + + diff --git a/sm-core/src/main/resources/templates/email/email_template_notification.ftl b/sm-core/src/main/resources/templates/email/email_template_notification.ftl new file mode 100755 index 0000000000..b6bea3bb45 --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_notification.ftl @@ -0,0 +1,326 @@ + + + + + + + + + + + + + + + + + + + + + +
    + +

    + + + + +
    +

    ${LOGOPATH}

    +
    +

    + +
    + + + + + + + + + + +
    + +
    + + + + +
    +

    +

    ${LABEL_HI} ${EMAIL_CUSTOMER_FIRSTNAME} ${EMAIL_CUSTOMER_LASTNAME}

    +

    +

    + ${EMAIL_NOTIFICATION_MESSAGE}
    + +

    +
    +
    + +
    + + + + + + + + + + + + diff --git a/sm-core/src/main/resources/templates/email/email_template_order_status.ftl b/sm-core/src/main/resources/templates/email/email_template_order_status.ftl new file mode 100755 index 0000000000..27dc2a848d --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_order_status.ftl @@ -0,0 +1,332 @@ + + + + + + + + + + + + + + + + + + + + + +
    + +

    + + + + +
    +

    ${LOGOPATH}

    +
    +

    + +
    + + + + + + + + + + +
    + +
    + + + + +
    +

    ${LABEL_HI} ${EMAIL_CUSTOMER_FIRSTNAME} ${EMAIL_CUSTOMER_LASTNAME}

    +

    + ${EMAIL_ORDER_STATUS_TEXT} +

    +

    + ${EMAIL_ORDER_STATUS} +

    + +

    + ${EMAIL_TEXT_STATUS_COMMENTS} +

    + + +
    +
    + +
    + + + + + + + + + + + + diff --git a/sm-core/src/main/resources/templates/email/email_template_outofstock.ftl b/sm-core/src/main/resources/templates/email/email_template_outofstock.ftl new file mode 100755 index 0000000000..a84d8610b4 --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_outofstock.ftl @@ -0,0 +1,49 @@ + + + + + + + + + + +
    + + + +
    +
    + ${EMAIL_STORE_NAME}

    + ${EMAIL_PRODUCT_TEXT}
    +
    +
    + +
    + + + + +
    +
    ${EMAIL_DISCLAIMER}
    +
    ${EMAIL_SPAM_DISCLAIMER}
    +
    + + diff --git a/sm-core/src/main/resources/templates/email/email_template_password_reset_customer.ftl b/sm-core/src/main/resources/templates/email/email_template_password_reset_customer.ftl new file mode 100755 index 0000000000..4fbc4a7a1b --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_password_reset_customer.ftl @@ -0,0 +1,334 @@ + + + + + + + + + + + + + + + + + + + + + + + +
    + +

    + + + + +
    + ${LOGOPATH} +
    +

    + +
    + + + + + + + + + +
    + +
    + + + + +
    +

    ${LABEL_HI} ${EMAIL_CUSTOMER_FIRSTNAME} ${EMAIL_CUSTOMER_LASTNAME}

    +

    + ${EMAIL_RESET_PASSWORD_TXT} +

    +

    + ${EMAIL_PASSWORD_LABEL}: ${EMAIL_CUSTOMER_PASSWORD}
    + +

    + +

    + ${EMAIL_CONTACT_OWNER} +

    + + +
    +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/sm-core/src/main/resources/templates/email/email_template_password_reset_request_customer.ftl b/sm-core/src/main/resources/templates/email/email_template_password_reset_request_customer.ftl new file mode 100755 index 0000000000..803b300d7f --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_password_reset_request_customer.ftl @@ -0,0 +1,334 @@ + + + + + + + + + + + + + + + + + + + + + + + +
    + +

    + + + + +
    + ${LOGOPATH} +
    +

    + +
    + + + + + + + + + +
    + +
    + + + + +
    +

    ${LABEL_HI} ${EMAIL_CUSTOMER_FIRSTNAME},

    +

    + ${RESET_PASSWORD_TEXT} +

    +

    + ${LABEL_LINK_TITLE} ${LABEL_LINK}
    + +

    + +

    + ${EMAIL_CONTACT_OWNER} +

    + + +
    +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/sm-core/src/main/resources/templates/email/email_template_password_reset_request_user.ftl b/sm-core/src/main/resources/templates/email/email_template_password_reset_request_user.ftl new file mode 100755 index 0000000000..58febb4d7b --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_password_reset_request_user.ftl @@ -0,0 +1,328 @@ + + + + + + + + + + + + + + + + + + + + + + + +
    + +

    + + + + +
    + ${LOGOPATH} +
    +

    + +
    + + + + + + + + + +
    + +
    + + + + +
    +

    ${LABEL_HI} ${EMAIL_USER_FIRSTNAME},

    +

    + ${RESET_PASSWORD_TEXT} +

    +

    + ${LABEL_LINK_TITLE} ${LABEL_LINK}
    + +

    +
    +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/sm-core/src/main/resources/templates/email/email_template_password_reset_user.ftl b/sm-core/src/main/resources/templates/email/email_template_password_reset_user.ftl new file mode 100755 index 0000000000..9b1a8bcf00 --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_password_reset_user.ftl @@ -0,0 +1,54 @@ + + + + + + + + + + +
    + + + ${LOGOPATH} + + + +
    +
    + ${EMAIL_STORE_NAME}

    +

    ${EMAIL_RESET_PASSWORD_TXT}


    + ${EMAIL_PASSWORD_LABEL}: ${EMAIL_USER_PASSWORD}

    + ${EMAIL_CONTACT_OWNER} +
    +
    + +
    + + + + +
    +
    ${EMAIL_DISCLAIMER}
    +
    ${EMAIL_SPAM_DISCLAIMER}
    +
    + + diff --git a/sm-core/src/main/resources/templates/email/email_template_sentinvoice.ftl b/sm-core/src/main/resources/templates/email/email_template_sentinvoice.ftl new file mode 100755 index 0000000000..f179795f31 --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_sentinvoice.ftl @@ -0,0 +1,55 @@ + + + + + + + + + + +
    + + + ${LOGOPATH} + + + +
    +
    + ${EMAIL_STORE_NAME}

    + ${EMAIL_GREETING} ${EMAIL_CUSTOMER_NAME}

    + ${EMAIL_INVOICE_MESSAGE}

    + ${EMAIL_INVOICE_PAYMENT_URL}

    + ${EMAIL_CONTACT_OWNER} +
    +
    + +
    + + + + +
    +
    ${EMAIL_DISCLAIMER}
    +
    ${EMAIL_SPAM_DISCLAIMER}
    +
    + + diff --git a/sm-core/src/main/resources/templates/email/email_template_user_confirm_emil.ftl b/sm-core/src/main/resources/templates/email/email_template_user_confirm_emil.ftl new file mode 100755 index 0000000000..6ec616b618 --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_user_confirm_emil.ftl @@ -0,0 +1,334 @@ + + + + + + + + + + + + + + + + + + + + + +
    + +

    + + + + +
    +

    ${LOGOPATH}

    +
    +

    + +
    + + + + + + + + + + +
    + +
    + + + + +
    +

    ${LABEL_HI} ${EMAIL_CUSTOMER_FIRSTNAME} ${EMAIL_CUSTOMER_LASTNAME}

    +

    + ${EMAIL_CUSTOMER_GREETING} +

    +

    + ${EMAIL_USERNAME_LABEL}: ${EMAIL_USER_NAME}
    + ${EMAIL_PASSWORD_LABEL}: ${EMAIL_CUSTOMER_PASSWORD}
    + +

    + +

    + ${CUSTOMER_ACCESS_LABEL} ${ACCESS_NOW_LABEL} » +

    + + +
    +
    + +
    + + + + + + + + + + + + diff --git a/sm-core/src/main/resources/templates/email/email_template_user_password_link.ftl b/sm-core/src/main/resources/templates/email/email_template_user_password_link.ftl new file mode 100755 index 0000000000..31053cc7f1 --- /dev/null +++ b/sm-core/src/main/resources/templates/email/email_template_user_password_link.ftl @@ -0,0 +1,49 @@ + + + + + + + + + + +
    + + +
    +
    + ${EMAIL_PASSWORD_TEXT}


    + ${EMAIL_PASSWORD_LINK}

    +

    +
    +
    + +
    + + + + +
    +
    ${EMAIL_DISCLAIMER}
    +
    ${EMAIL_SPAM_DISCLAIMER}
    +
    + + diff --git a/sm-core/src/main/resources/templates/invoice/Invoice.ods b/sm-core/src/main/resources/templates/invoice/Invoice.ods new file mode 100755 index 0000000000..f93641937f Binary files /dev/null and b/sm-core/src/main/resources/templates/invoice/Invoice.ods differ diff --git a/sm-core/src/main/resources/templates/invoice/Invoice_es.ods b/sm-core/src/main/resources/templates/invoice/Invoice_es.ods new file mode 100644 index 0000000000..2ebd9b7a2c Binary files /dev/null and b/sm-core/src/main/resources/templates/invoice/Invoice_es.ods differ diff --git a/sm-core/src/main/resources/templates/invoice/Invoice_fr.ods b/sm-core/src/main/resources/templates/invoice/Invoice_fr.ods new file mode 100755 index 0000000000..6c453a52b0 Binary files /dev/null and b/sm-core/src/main/resources/templates/invoice/Invoice_fr.ods differ diff --git a/sm-core/src/test/java/com/salesmanager/test/business/utils/DataUtilsTest.java b/sm-core/src/test/java/com/salesmanager/test/business/utils/DataUtilsTest.java new file mode 100644 index 0000000000..1c1a954d13 --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/business/utils/DataUtilsTest.java @@ -0,0 +1,109 @@ +package com.salesmanager.test.business.utils; + +import com.salesmanager.core.business.utils.DataUtils; +import com.salesmanager.core.constants.MeasureUnit; +import com.salesmanager.core.model.merchant.MerchantStore; + +import org.junit.Test; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class DataUtilsTest { + + /** + * This methods tests {@link DataUtils#trimPostalCode(String)} + */ + @Test + public void testTrimPostalCode(){ + String result = DataUtils.trimPostalCode(" 364856-A56 - B888@ "); + assertEquals("364856A56B888", result); + } + + /** + * This methods tests {@link DataUtils#getWeight(double, MerchantStore, String)} + */ + @Test + public void testGetWeight_When_StoreUnit_LB_MeasurementUnit_LB(){ + MerchantStore store = mock(MerchantStore.class); + when(store.getWeightunitcode()).thenReturn(MeasureUnit.LB.name()); + double result = DataUtils.getWeight(100.789, store, MeasureUnit.LB.name()); + assertEquals(100.79, result, 0); + } + + /** + * This methods tests {@link DataUtils#getWeight(double, MerchantStore, String)} + */ + @Test + public void testGetWeight_When_StoreUnit_KG_MeasurementUnit_LB(){ + MerchantStore store = mock(MerchantStore.class); + when(store.getWeightunitcode()).thenReturn(MeasureUnit.KG.name()); + double result = DataUtils.getWeight(100.789, store, MeasureUnit.LB.name()); + assertEquals(221.74, result, 0); + } + + /** + * This methods tests {@link DataUtils#getWeight(double, MerchantStore, String)} + */ + @Test + public void testGetWeight_When_StoreUnit_KG_MeasurementUnit_KG(){ + MerchantStore store = mock(MerchantStore.class); + when(store.getWeightunitcode()).thenReturn(MeasureUnit.KG.name()); + double result = DataUtils.getWeight(100.789, store, MeasureUnit.KG.name()); + assertEquals(100.79, result, 0); + } + + /** + * This methods tests {@link DataUtils#getWeight(double, MerchantStore, String)} + */ + @Test + public void testGetWeight_When_StoreUnit_LB_MeasurementUnit_KG(){ + MerchantStore store = mock(MerchantStore.class); + when(store.getWeightunitcode()).thenReturn(MeasureUnit.LB.name()); + double result = DataUtils.getWeight(100.789, store, MeasureUnit.KG.name()); + assertEquals(45.81, result, 0); + } + + /** + * This methods tests {@link DataUtils#getMeasure(double, MerchantStore, String)} + */ + @Test + public void testGetMeasureWhen_StoreUnit_IN_MeasurementUnit_IN(){ + MerchantStore store = mock(MerchantStore.class); + when(store.getSeizeunitcode()).thenReturn(MeasureUnit.IN.name()); + double result = DataUtils.getMeasure(100.789, store, MeasureUnit.IN.name()); + assertEquals(100.79, result, 0); + } + + /** + * This methods tests {@link DataUtils#getMeasure(double, MerchantStore, String)} + */ + @Test + public void testGetMeasureWhen_StoreUnit_CM_MeasurementUnit_IN(){ + MerchantStore store = mock(MerchantStore.class); + when(store.getSeizeunitcode()).thenReturn(MeasureUnit.CM.name()); + double result = DataUtils.getMeasure(100.789, store, MeasureUnit.IN.name()); + assertEquals(256.00, result, 0); + } + + /** + * This methods tests {@link DataUtils#getMeasure(double, MerchantStore, String)} + */ + @Test + public void testGetMeasureWhen_StoreUnit_CM_MeasurementUnit_CM(){ + MerchantStore store = mock(MerchantStore.class); + when(store.getSeizeunitcode()).thenReturn(MeasureUnit.CM.name()); + double result = DataUtils.getMeasure(100.789, store, MeasureUnit.CM.name()); + assertEquals(100.79, result, 0); + } + + /** + * This methods tests {@link DataUtils#getMeasure(double, MerchantStore, String)} + */ + @Test + public void testGetMeasureWhen_StoreUnit_IN_MeasurementUnit_CM(){ + MerchantStore store = mock(MerchantStore.class); + when(store.getSeizeunitcode()).thenReturn(MeasureUnit.IN.name()); + double result = DataUtils.getMeasure(100.789, store, MeasureUnit.CM.name()); + assertEquals(39.31, result, 0); + } +} diff --git a/sm-core/src/test/java/com/salesmanager/test/catalog/CategoryTest.java b/sm-core/src/test/java/com/salesmanager/test/catalog/CategoryTest.java new file mode 100755 index 0000000000..95f92c73a7 --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/catalog/CategoryTest.java @@ -0,0 +1,67 @@ +package com.salesmanager.test.catalog; + +import static org.junit.Assert.assertNotNull; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Test; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.category.CategoryDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + + +public class CategoryTest extends com.salesmanager.test.common.AbstractSalesManagerCoreTestCase { + + /** + * This method creates multiple products using multiple catalog APIs + * @throws ServiceException + */ + @Test + public void testCategory() throws Exception { + + Language en = languageService.getByCode("en"); + Language fr = languageService.getByCode("fr"); + + MerchantStore store = merchantService.getByCode(MerchantStore.DEFAULT_STORE); + + Category materingstuff = new Category(); + materingstuff.setMerchantStore(store); + materingstuff.setCode("materingstuff"); + + CategoryDescription bookEnglishDescription = new CategoryDescription(); + bookEnglishDescription.setName("Book"); + bookEnglishDescription.setCategory(materingstuff); + bookEnglishDescription.setLanguage(en); + + CategoryDescription bookFrenchDescription = new CategoryDescription(); + bookFrenchDescription.setName("Livre"); + bookFrenchDescription.setCategory(materingstuff); + bookFrenchDescription.setLanguage(fr); + + Set descriptions = new HashSet(); + descriptions.add(bookEnglishDescription); + descriptions.add(bookFrenchDescription); + materingstuff.setDescriptions(descriptions); + + categoryService.create(materingstuff); + + assertNotNull(materingstuff.getId()); + + Long bookId = materingstuff.getId(); + + Category fetchedBook = categoryService.getById(bookId, store.getId()); + Assert.assertEquals(2, fetchedBook.getDescriptions().size()); + + // Clean up for other tests + categoryService.delete(materingstuff); + + } + + + +} \ No newline at end of file diff --git a/sm-core/src/test/java/com/salesmanager/test/catalog/ManufacturerTest.java b/sm-core/src/test/java/com/salesmanager/test/catalog/ManufacturerTest.java new file mode 100644 index 0000000000..3cf7fa2fc6 --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/catalog/ManufacturerTest.java @@ -0,0 +1,75 @@ +package com.salesmanager.test.catalog; + +import org.junit.Test; +import org.springframework.data.domain.Page; +import org.springframework.util.Assert; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.catalog.product.manufacturer.ManufacturerDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + + +public class ManufacturerTest extends com.salesmanager.test.common.AbstractSalesManagerCoreTestCase { + + /** + * This method creates multiple products using multiple catalog APIs + * @throws ServiceException + */ + @Test + public void testManufacturer() throws Exception { + + Language en = languageService.getByCode("en"); + + MerchantStore store = merchantService.getByCode(MerchantStore.DEFAULT_STORE); + + Manufacturer oreilley = new Manufacturer(); + oreilley.setMerchantStore(store); + oreilley.setCode("oreilley2"); + + ManufacturerDescription oreilleyd = new ManufacturerDescription(); + oreilleyd.setLanguage(en); + oreilleyd.setName("O\'reilley"); + oreilleyd.setManufacturer(oreilley); + oreilley.getDescriptions().add(oreilleyd); + + manufacturerService.create(oreilley); + + Manufacturer packed = new Manufacturer(); + packed.setMerchantStore(store); + packed.setCode("packed2"); + + ManufacturerDescription packedd = new ManufacturerDescription(); + packedd.setLanguage(en); + packedd.setManufacturer(packed); + packedd.setName("Packed publishing"); + packed.getDescriptions().add(packedd); + + manufacturerService.create(packed); + + Manufacturer novells = new Manufacturer(); + novells.setMerchantStore(store); + novells.setCode("novells2"); + + ManufacturerDescription novellsd = new ManufacturerDescription(); + novellsd.setLanguage(en); + novellsd.setManufacturer(novells); + novellsd.setName("Novells publishing"); + novells.getDescriptions().add(novellsd); + + manufacturerService.create(novells); + + + //query pageable category + Page pageable = manufacturerService.listByStore(store, en, 0, 5); + Assert.isTrue(pageable.getSize()>0, "4 manufacturers"); + + } + + + + + + + +} \ No newline at end of file diff --git a/sm-core/src/test/java/com/salesmanager/test/catalog/ProductNextGenTest.java b/sm-core/src/test/java/com/salesmanager/test/catalog/ProductNextGenTest.java new file mode 100644 index 0000000000..5273394891 --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/catalog/ProductNextGenTest.java @@ -0,0 +1,423 @@ +package com.salesmanager.test.catalog; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertNotNull; + +import java.math.BigDecimal; +import java.sql.Date; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.Test; +import org.springframework.data.domain.Page; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.category.CategoryDescription; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.ProductCriteria; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionSet; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionType; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValueDescription; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.description.ProductDescription; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.catalog.product.manufacturer.ManufacturerDescription; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPriceDescription; +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + + +public class ProductNextGenTest extends com.salesmanager.test.common.AbstractSalesManagerCoreTestCase { + + private static final Date date = new Date(System.currentTimeMillis()); + + private ProductOptionValue nine = null; + private ProductOptionValue nineHalf = null; + private ProductOptionValue ten = null; + private ProductOption size = null; + + private ProductOptionSet possibleSizes; + + + + /** + * This method creates single product with variants using multiple catalog APIs + * @throws ServiceException + */ + @Test + public void testCreateProduct() throws Exception { + + Language en = languageService.getByCode("en"); + + MerchantStore store = merchantService.getByCode(MerchantStore.DEFAULT_STORE); + ProductType generalType = productTypeService.getProductType(ProductType.GENERAL_TYPE); + + /** + * Category + */ + Category shoes = new Category(); + shoes.setMerchantStore(store); + shoes.setCode("shoes"); + + CategoryDescription shoesDescription = new CategoryDescription(); + shoesDescription.setName("Shoes"); + shoesDescription.setCategory(shoes); + shoesDescription.setLanguage(en); + + Set descriptions = new HashSet(); + descriptions.add(shoesDescription); + + shoes.setDescriptions(descriptions); + + categoryService.create(shoes); + // + + /** + * Manufacturer / Brand + */ + + Manufacturer brown = new Manufacturer(); + brown.setMerchantStore(store); + brown.setCode("brown"); + + ManufacturerDescription brownd = new ManufacturerDescription(); + brownd.setLanguage(en); + brownd.setName("Brown's"); + brownd.setManufacturer(brown); + brown.getDescriptions().add(brownd); + + manufacturerService.create(brown); + // + + + // PRODUCT + + // -- non variable informations + + Product summerShoes = new Product(); + summerShoes.setProductHeight(new BigDecimal(3)); + summerShoes.setProductLength(new BigDecimal(9));//average + summerShoes.setProductWidth(new BigDecimal(4)); + summerShoes.setSku("BR12345"); + summerShoes.setManufacturer(brown); + summerShoes.setType(generalType); + summerShoes.setMerchantStore(store); + + //is available + summerShoes.setAvailable(true); + + // Product description + ProductDescription description = new ProductDescription(); + description.setName("Summer shoes"); + description.setLanguage(en); + description.setProduct(summerShoes); + + summerShoes.getDescriptions().add(description); + + //add product to shoes category + summerShoes.getCategories().add(shoes); + + // -- end non variable informations + + // --- add attributes to the product (size) + createOptions(summerShoes); + + // --- options set + /** + * Option Set facilitates product attributes creation for redundant product creation + * it offers a list of possible options and options values administrator can create in order + * to easily create attributes + */ + createOptionsSet(store); + + // --- create attributes (available options) + /** + * Add options to product + * Those are attributes + */ + + ProductAttribute size_nine = new ProductAttribute(); + size_nine.setProduct(summerShoes); + size_nine.setProductOption(size); + size_nine.setAttributeDefault(true); + size_nine.setProductAttributePrice(new BigDecimal(0));//no price variation + size_nine.setProductAttributeWeight(new BigDecimal(0));//no weight variation + size_nine.setProductOptionValue(nine); + + summerShoes.getAttributes().add(size_nine); + + + ProductAttribute size_nine_half = new ProductAttribute(); + size_nine_half.setProduct(summerShoes); + size_nine_half.setProductOption(size); + size_nine_half.setProductAttributePrice(new BigDecimal(0));//no price variation + size_nine_half.setProductAttributeWeight(new BigDecimal(0));//weight variation + size_nine_half.setProductOptionValue(nineHalf); + + summerShoes.getAttributes().add(size_nine_half); + + + ProductAttribute size_ten = new ProductAttribute(); + size_ten.setProduct(summerShoes); + size_ten.setProductOption(size); + size_ten.setProductAttributePrice(new BigDecimal(0));//no price variation + size_ten.setProductAttributeWeight(new BigDecimal(0));//weight variation + size_ten.setProductOptionValue(ten); + + summerShoes.getAttributes().add(size_ten); + + + // ---- variable informations - inventory - variants - prices + ProductAvailability availability = createInventory(store, 100, new BigDecimal("99.99")); + summerShoes.getAvailabilities().add(availability); + // ---- add available sizes + + //DEFAULT (total quantity of 100 distributed) + + //TODO use pre 3.0 variation + + //40 of 9 +/* ProductVariant size_nine_DEFAULT = new ProductVariant(); + size_nine_DEFAULT.setAttribute(size_nine); + size_nine_DEFAULT.setProductQuantity(40); + size_nine_DEFAULT.setProductAvailability(availability);*/ + + //availability.getVariants().add(size_nine_DEFAULT); + + //30 of 9.5 +/* ProductVariant size_nine_half_DEFAULT = new ProductVariant(); + size_nine_half_DEFAULT.setAttribute(size_nine_half); + size_nine_half_DEFAULT.setProductQuantity(30); + size_nine_half_DEFAULT.setProductAvailability(availability);*/ + + //availability.getVariants().add(size_nine_half_DEFAULT); + + //30 of ten +/* ProductVariant size_ten_DEFAULT = new ProductVariant(); + size_ten_DEFAULT.setAttribute(size_nine_half); + size_ten_DEFAULT.setProductQuantity(30); + size_ten_DEFAULT.setProductAvailability(availability);*/ + + //availability.getVariants().add(size_ten_DEFAULT); + + //inventory for store DEFAULT and product summerShoes + availability.setProduct(summerShoes); + availability.setMerchantStore(store); + + + /** + * Create product + */ + productService.saveProduct(summerShoes); + + //ObjectMapper mapper = new ObjectMapper(); + //Converting the Object to JSONString + //String jsonString = mapper.writeValueAsString(summerShoes); + //System.out.println(jsonString); + + Product p = productService.getById(summerShoes.getId()); + assertNotNull(p); + + //List avs = p.getAvailabilities().stream().filter(a -> !a.getVariants().isEmpty()).collect(Collectors.toList()); + //assertThat(avs, not(empty())); + + //test product list service + + //list products per category + //list 5 items + ProductCriteria productCriteria = new ProductCriteria(); + productCriteria.setCategoryIds(Stream.of(shoes.getId()) + .collect(Collectors.toList())); + + Page listByCategory = productService.listByStore(store, en, productCriteria, 0, 5); + List productsByCategory = listByCategory.getContent(); + assertThat(productsByCategory, not(empty())); + + //list products per color attribute + Page listByOptionValue = productService.listByStore(store, en, productCriteria, 0, 5); + productCriteria = new ProductCriteria(); + productCriteria.setOptionValueIds(Stream.of(nineHalf.getId()) + .collect(Collectors.toList())); + List productsByOption = listByOptionValue.getContent(); + assertThat(productsByOption, not(empty())); + + + + } + + private void createOptionsSet(MerchantStore store) throws Exception { + + //add a set of option / values for major sizes + possibleSizes = new ProductOptionSet(); + possibleSizes.setCode("majorSizes"); + possibleSizes.setStore(store); + possibleSizes.setOption(size); + + + List values = new ArrayList(); + values.add(nine); + values.add(ten); + + possibleSizes.setValues(values); + + + productOptionSetService.create(possibleSizes); + + } + + /** + * Manage product inventory + * @param product + * @throws Exception + */ + private ProductAvailability createInventory(MerchantStore store, int quantity, BigDecimal price) throws Exception { + + //add inventory + ProductAvailability availability = new ProductAvailability(); + availability.setProductDateAvailable(date); + availability.setProductQuantity(quantity); + availability.setRegion("*"); + availability.setAvailable(true); + + Language en = languageService.getByCode("en"); + + ProductPrice dprice = new ProductPrice(); + dprice.setDefaultPrice(true); + dprice.setProductPriceAmount(price); + dprice.setProductAvailability(availability); + + ProductPriceDescription dpd = new ProductPriceDescription(); + dpd.setName("Base price"); + dpd.setProductPrice(dprice); + dpd.setLanguage(en); + + dprice.getDescriptions().add(dpd); + availability.getPrices().add(dprice); + + return availability; + + + + } + + + /** + * Add possible choices + * @param product + * @throws Exception + */ + private void createOptions(Product product) throws Exception { + + + /** + * An attribute can be created dynamicaly but the attached Option and Option value need to exist + */ + + MerchantStore store = product.getMerchantStore(); + Language en = languageService.getByCode("en"); + + + /** + * Create size option + */ + size = new ProductOption(); + size.setMerchantStore(store); + size.setCode("SHOESIZE"); + size.setProductOptionType(ProductOptionType.Radio.name()); + + ProductOptionDescription sizeDescription = new ProductOptionDescription(); + sizeDescription.setLanguage(en); + sizeDescription.setName("Size"); + sizeDescription.setDescription("Show size"); + sizeDescription.setProductOption(size); + + size.getDescriptions().add(sizeDescription); + + //create option + productOptionService.saveOrUpdate(size); + + + /** + * Create size values (9, 9.5, 10) + */ + + //option value 9 + nine = new ProductOptionValue(); + nine.setMerchantStore(store); + nine.setCode("nine"); + + ProductOptionValueDescription nineDescription = new ProductOptionValueDescription(); + nineDescription.setLanguage(en); + nineDescription.setName("9"); + nineDescription.setDescription("Size 9"); + nineDescription.setProductOptionValue(nine); + + nine.getDescriptions().add(nineDescription); + + //create an option value + productOptionValueService.saveOrUpdate(nine); + + + //option value 9.5 + nineHalf = new ProductOptionValue(); + nineHalf.setMerchantStore(store); + nineHalf.setCode("nineHalf"); + + ProductOptionValueDescription nineHalfDescription = new ProductOptionValueDescription(); + nineHalfDescription.setLanguage(en); + nineHalfDescription.setName("9.5"); + nineHalfDescription.setDescription("Size 9.5"); + nineHalfDescription.setProductOptionValue(nineHalf); + + nineHalf.getDescriptions().add(nineHalfDescription); + + //create an option value + productOptionValueService.saveOrUpdate(nineHalf); + + + //option value 10 + ten = new ProductOptionValue(); + ten.setMerchantStore(store); + ten.setCode("ten"); + + ProductOptionValueDescription tenDescription = new ProductOptionValueDescription(); + tenDescription.setLanguage(en); + tenDescription.setName("10"); + tenDescription.setDescription("Size 10"); + tenDescription.setProductOptionValue(ten); + + ten.getDescriptions().add(tenDescription); + + //create an option value + productOptionValueService.saveOrUpdate(ten); + + + // end options / options values + + + } + + + + + + + + + + + +} \ No newline at end of file diff --git a/sm-core/src/test/java/com/salesmanager/test/catalog/ProductTest.java b/sm-core/src/test/java/com/salesmanager/test/catalog/ProductTest.java new file mode 100755 index 0000000000..31568b55b8 --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/catalog/ProductTest.java @@ -0,0 +1,682 @@ +package com.salesmanager.test.catalog; + +import java.io.InputStream; +import java.math.BigDecimal; +import java.sql.Date; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.junit.Assert; +import org.junit.Test; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.category.CategoryDescription; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionType; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValueDescription; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.description.ProductDescription; +import com.salesmanager.core.model.catalog.product.file.ProductImageSize; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.catalog.product.manufacturer.ManufacturerDescription; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPriceDescription; +import com.salesmanager.core.model.catalog.product.relationship.ProductRelationship; +import com.salesmanager.core.model.catalog.product.review.ProductReview; +import com.salesmanager.core.model.catalog.product.review.ProductReviewDescription; +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.ImageContentFile; +import com.salesmanager.core.model.content.OutputContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + + +public class ProductTest extends com.salesmanager.test.common.AbstractSalesManagerCoreTestCase { + + private static final Date date = new Date(System.currentTimeMillis()); + + private final String IMAGE_NAME = "icon.png"; + + /** + * This method creates multiple products using multiple catalog APIs + * @throws ServiceException + */ + @Test + public void testCreateProduct() throws Exception { + + Language en = languageService.getByCode("en"); + Language fr = languageService.getByCode("fr"); + + MerchantStore store = merchantService.getByCode(MerchantStore.DEFAULT_STORE); + ProductType generalType = productTypeService.getProductType(ProductType.GENERAL_TYPE); + + Category book = new Category(); + book.setMerchantStore(store); + book.setCode("book"); + + CategoryDescription bookEnglishDescription = new CategoryDescription(); + bookEnglishDescription.setName("Book"); + bookEnglishDescription.setCategory(book); + bookEnglishDescription.setLanguage(en); + + CategoryDescription bookFrenchDescription = new CategoryDescription(); + bookFrenchDescription.setName("Livre"); + bookFrenchDescription.setCategory(book); + bookFrenchDescription.setLanguage(fr); + + Set descriptions = new HashSet(); + descriptions.add(bookEnglishDescription); + descriptions.add(bookFrenchDescription); + + book.setDescriptions(descriptions); + + categoryService.create(book); + + Category music = new Category(); + music.setMerchantStore(store); + music.setCode("music"); + + CategoryDescription musicEnglishDescription = new CategoryDescription(); + musicEnglishDescription.setName("Music"); + musicEnglishDescription.setCategory(music); + musicEnglishDescription.setLanguage(en); + + CategoryDescription musicFrenchDescription = new CategoryDescription(); + musicFrenchDescription.setName("Musique"); + musicFrenchDescription.setCategory(music); + musicFrenchDescription.setLanguage(fr); + + Set descriptions2 = new HashSet(); + descriptions2.add(musicEnglishDescription); + descriptions2.add(musicFrenchDescription); + + music.setDescriptions(descriptions2); + + categoryService.create(music); + + Category novell = new Category(); + novell.setMerchantStore(store); + novell.setCode("novell"); + + CategoryDescription novellEnglishDescription = new CategoryDescription(); + novellEnglishDescription.setName("Novell"); + novellEnglishDescription.setCategory(novell); + novellEnglishDescription.setLanguage(en); + + CategoryDescription novellFrenchDescription = new CategoryDescription(); + novellFrenchDescription.setName("Roman"); + novellFrenchDescription.setCategory(novell); + novellFrenchDescription.setLanguage(fr); + + Set descriptions3 = new HashSet(); + descriptions3.add(novellEnglishDescription); + descriptions3.add(novellFrenchDescription); + + novell.setDescriptions(descriptions3); + + novell.setParent(book); + + categoryService.create(novell); + categoryService.addChild(book, novell); + + Category tech = new Category(); + tech.setMerchantStore(store); + tech.setCode("tech"); + + CategoryDescription techEnglishDescription = new CategoryDescription(); + techEnglishDescription.setName("Technology"); + techEnglishDescription.setCategory(tech); + techEnglishDescription.setLanguage(en); + + CategoryDescription techFrenchDescription = new CategoryDescription(); + techFrenchDescription.setName("Technologie"); + techFrenchDescription.setCategory(tech); + techFrenchDescription.setLanguage(fr); + + Set descriptions4 = new HashSet(); + descriptions4.add(techFrenchDescription); + descriptions4.add(techFrenchDescription); + + tech.setDescriptions(descriptions4); + + tech.setParent(book); + + categoryService.create(tech); + categoryService.addChild(book, tech); + + Category fiction = new Category(); + fiction.setMerchantStore(store); + fiction.setCode("fiction"); + + CategoryDescription fictionEnglishDescription = new CategoryDescription(); + fictionEnglishDescription.setName("Fiction"); + fictionEnglishDescription.setCategory(fiction); + fictionEnglishDescription.setLanguage(en); + + CategoryDescription fictionFrenchDescription = new CategoryDescription(); + fictionFrenchDescription.setName("Sc Fiction"); + fictionFrenchDescription.setCategory(fiction); + fictionFrenchDescription.setLanguage(fr); + + Set fictiondescriptions = new HashSet(); + fictiondescriptions.add(fictionEnglishDescription); + fictiondescriptions.add(fictionFrenchDescription); + + fiction.setDescriptions(fictiondescriptions); + + fiction.setParent(novell); + + categoryService.create(fiction); + categoryService.addChild(book, fiction); + + Manufacturer oreilley = new Manufacturer(); + oreilley.setMerchantStore(store); + oreilley.setCode("oreilley"); + + ManufacturerDescription oreilleyd = new ManufacturerDescription(); + oreilleyd.setLanguage(en); + oreilleyd.setName("O\'reilley"); + oreilleyd.setManufacturer(oreilley); + oreilley.getDescriptions().add(oreilleyd); + + manufacturerService.create(oreilley); + + Manufacturer packed = new Manufacturer(); + packed.setMerchantStore(store); + packed.setCode("packed"); + + ManufacturerDescription packedd = new ManufacturerDescription(); + packedd.setLanguage(en); + packedd.setManufacturer(packed); + packedd.setName("Packed publishing"); + packed.getDescriptions().add(packedd); + + manufacturerService.create(packed); + + Manufacturer novells = new Manufacturer(); + novells.setMerchantStore(store); + novells.setCode("novells"); + + ManufacturerDescription novellsd = new ManufacturerDescription(); + novellsd.setLanguage(en); + novellsd.setManufacturer(novells); + novellsd.setName("Novells publishing"); + novells.getDescriptions().add(novellsd); + + manufacturerService.create(novells); + + // PRODUCT 1 + + Product product = new Product(); + product.setProductHeight(new BigDecimal(4)); + product.setProductLength(new BigDecimal(3)); + product.setProductWidth(new BigDecimal(1)); + product.setSku("CT12345"); + product.setManufacturer(oreilley); + product.setType(generalType); + product.setMerchantStore(store); + + // Product description + ProductDescription description = new ProductDescription(); + description.setName("Spring in Action"); + description.setLanguage(en); + description.setProduct(product); + + product.getDescriptions().add(description); + + //add category + product.getCategories().add(tech); + + + + // Availability + ProductAvailability availability = new ProductAvailability(); + availability.setProductDateAvailable(date); + availability.setProductQuantity(100); + availability.setRegion("*"); + availability.setProduct(product);// associate with product + + //productAvailabilityService.create(availability); + product.getAvailabilities().add(availability); + + ProductPrice dprice = new ProductPrice(); + dprice.setDefaultPrice(true); + dprice.setProductPriceAmount(new BigDecimal(29.99)); + dprice.setProductAvailability(availability); + + ProductPriceDescription dpd = new ProductPriceDescription(); + dpd.setName("Base price"); + dpd.setProductPrice(dprice); + dpd.setLanguage(en); + + dprice.getDescriptions().add(dpd); + availability.getPrices().add(dprice); + + + /** + * Create product + */ + productService.saveProduct(product); + + + /** + * Creates a review + * TODO requires customer + */ + //testReview(product); + + List products = productService.listByStore(store); + + System.out.println("Total number of items " + products.size()); + + //count products by category + String lineage = new StringBuilder().append(book.getLineage()).toString(); + + List categories = categoryService.getListByLineage(store, lineage); + + List ids = new ArrayList(); + if(categories!=null && categories.size()>0) { + for(Category c : categories) { + ids.add(c.getId()); + } + } + + List objs = categoryService.countProductsByCategories(store, ids); + + for(Object[] ob : objs) { + Long c = (Long) ob[0]; + //System.out.println("Category " + c.getCode() + " has " + ob[1] + " items"); + } + + //get manufacturer for given categories + List manufacturers = manufacturerService.listByProductsByCategoriesId(store, ids, en); + + //System.out.println("Number of manufacturer for all category " + manufacturers.size()); + + //Update product -- get first from the list + Product updatableProduct = products.get(0); + + //Get first availability, which is the only one created + ProductAvailability updatableAvailability = updatableProduct.getAvailabilities().iterator().next(); + + //Get first price, which is the only one created + ProductPrice updatablePrice = updatableAvailability.getPrices().iterator().next(); + updatablePrice.setProductPriceAmount(new BigDecimal(19.99)); + + + //Add a second price + ProductPrice anotherPrice = new ProductPrice(); + anotherPrice.setCode("eco"); + anotherPrice.setProductPriceAmount(new BigDecimal(1.99)); + anotherPrice.setProductAvailability(updatableAvailability); + + ProductPriceDescription anotherPriceD = new ProductPriceDescription(); + anotherPriceD.setName("Eco price"); + anotherPriceD.setProductPrice(anotherPrice); + anotherPriceD.setLanguage(en); + + anotherPrice.getDescriptions().add(anotherPriceD); + updatableAvailability.getPrices().add(anotherPrice); + + //Update product + productService.update(updatableProduct); + + + //go and get products again + products = productService.listByStore(store); + + updatableProduct = products.get(0); + + //test attributes + this.testAttributes(updatableProduct); + + + //test insert, view image + testInsertImage(updatableProduct); + testViewImage(updatableProduct); + + Product refreshed = productService.getBySku("CT12345", store, en); + productService.delete(refreshed); + + + + } + + + private void testAttributes(Product product) throws Exception { + + + /** + * An attribute can be created dynamicaly but the attached Option and Option value need to exist + */ + + MerchantStore store = product.getMerchantStore(); + + Language en = languageService.getByCode("en"); + + /** + * Create size option + */ + ProductOption color = new ProductOption(); + color.setMerchantStore(store); + color.setCode("COLOR"); + color.setProductOptionType(ProductOptionType.Radio.name()); + + ProductOptionDescription optionDescription = new ProductOptionDescription(); + optionDescription.setLanguage(en); + optionDescription.setName("Color"); + optionDescription.setDescription("Color of an item"); + optionDescription.setProductOption(color); + + color.getDescriptions().add(optionDescription); + + //create option + productOptionService.saveOrUpdate(color); + + /** + * Create size option + */ + ProductOption size = new ProductOption(); + size.setMerchantStore(store); + size.setCode("SIZE"); + size.setProductOptionType(ProductOptionType.Radio.name()); + + ProductOptionDescription sizeDescription = new ProductOptionDescription(); + sizeDescription.setLanguage(en); + sizeDescription.setName("Size"); + sizeDescription.setDescription("Size of an item"); + sizeDescription.setProductOption(size); + + size.getDescriptions().add(sizeDescription); + + //create option + productOptionService.saveOrUpdate(size); + + + //option value + ProductOptionValue red = new ProductOptionValue(); + red.setMerchantStore(store); + red.setCode("red"); + + ProductOptionValueDescription redDescription = new ProductOptionValueDescription(); + redDescription.setLanguage(en); + redDescription.setName("Red"); + redDescription.setDescription("Red color"); + redDescription.setProductOptionValue(red); + + red.getDescriptions().add(redDescription); + + //create an option value + productOptionValueService.saveOrUpdate(red); + + //another option value + ProductOptionValue blue = new ProductOptionValue(); + blue.setMerchantStore(store); + blue.setCode("blue"); + + ProductOptionValueDescription blueDescription = new ProductOptionValueDescription(); + blueDescription.setLanguage(en); + blueDescription.setName("Blue"); + blueDescription.setDescription("Color blue"); + blueDescription.setProductOptionValue(blue); + + blue.getDescriptions().add(blueDescription); + + //create another option value + productOptionValueService.saveOrUpdate(blue); + + //option value + ProductOptionValue small = new ProductOptionValue(); + small.setMerchantStore(store); + small.setCode("small"); + + ProductOptionValueDescription smallDescription = new ProductOptionValueDescription(); + smallDescription.setLanguage(en); + smallDescription.setName("Small"); + smallDescription.setDescription("Small size"); + smallDescription.setProductOptionValue(small); + + small.getDescriptions().add(smallDescription); + + //create an option value + productOptionValueService.saveOrUpdate(small); + + //another option value + ProductOptionValue medium = new ProductOptionValue(); + medium.setMerchantStore(store); + medium.setCode("medium"); + + ProductOptionValueDescription mediumDescription = new ProductOptionValueDescription(); + mediumDescription.setLanguage(en); + mediumDescription.setName("Medium"); + mediumDescription.setDescription("Medium size"); + mediumDescription.setProductOptionValue(medium); + + medium.getDescriptions().add(mediumDescription); + + //create another option value + productOptionValueService.saveOrUpdate(medium); + + + ProductAttribute color_blue = new ProductAttribute(); + color_blue.setProduct(product); + color_blue.setProductOption(color); + color_blue.setAttributeDefault(true); + color_blue.setProductAttributePrice(new BigDecimal(0));//no price variation + color_blue.setProductAttributeWeight(new BigDecimal(1));//weight variation + color_blue.setProductOptionValue(blue); + + productAttributeService.create(color_blue); + + product.getAttributes().add(color_blue); + + + /** create attributes **/ + //attributes + ProductAttribute color_red = new ProductAttribute(); + color_red.setProduct(product); + color_red.setProductOption(color); + color_red.setAttributeDefault(true); + color_red.setProductAttributePrice(new BigDecimal(0));//no price variation + color_red.setProductAttributeWeight(new BigDecimal(1));//weight variation + color_red.setProductOptionValue(red); + + productAttributeService.create(color_red); + + product.getAttributes().add(color_red); + + + ProductAttribute smallAttr = new ProductAttribute(); + smallAttr.setProduct(product); + smallAttr.setProductOption(size); + smallAttr.setAttributeDefault(true); + smallAttr.setProductAttributePrice(new BigDecimal(0));//no price variation + smallAttr.setProductAttributeWeight(new BigDecimal(1));//weight variation + smallAttr.setProductOptionValue(small); + + productAttributeService.create(smallAttr); + + product.getAttributes().add(smallAttr); + + productService.update(product); + + /** + * get options facets + */ + + List attributes = productAttributeService.getProductAttributesByCategoryLineage(store, product.getCategories().iterator().next().getLineage(), en); + Assert.assertTrue((long) attributes.size() > 0); + + } + + /** + * Images + * @param product + * @throws Exception + */ + private void testInsertImage(Product product) throws Exception { + + + ProductImage productImage = new ProductImage(); + + ClassLoader classloader = Thread.currentThread().getContextClassLoader(); + InputStream inputStream = classloader.getResourceAsStream("img/" + IMAGE_NAME); + + + ImageContentFile cmsContentImage = new ImageContentFile(); + cmsContentImage.setFileName( IMAGE_NAME ); + cmsContentImage.setFile( inputStream ); + cmsContentImage.setFileContentType(FileContentType.PRODUCT); + + + productImage.setProductImage(IMAGE_NAME); + productImage.setProduct(product); + + //absolutely required otherwise the file is not created on disk + productImage.setImage(inputStream); + + product.getImages().add(productImage); + + productService.update(product);//saves the ProductImage entity and the file on disk + + + + + } + + private void testViewImage(Product product) throws Exception { + + + ProductImage productImage = product.getProductImage(); + + //get physical small image + OutputContentFile contentFile = productImageService.getProductImage(product.getMerchantStore().getCode(), product.getSku(), productImage.getProductImage(), ProductImageSize.SMALL); + + Assert.assertNotNull(contentFile); + + //get physical original image + contentFile = productImageService.getProductImage(product.getMerchantStore().getCode(), product.getSku(), productImage.getProductImage(), ProductImageSize.LARGE); + + Assert.assertNotNull(contentFile); + + + } + + + //REVIEW + private void testReview(Product product) throws Exception { + + ProductReview review = new ProductReview(); + review.setProduct(product); + review.setReviewRating(4d); + Language en = languageService.getByCode("en"); + + ProductReviewDescription reviewDescription = new ProductReviewDescription(); + reviewDescription.setLanguage(en); + reviewDescription.setDescription("This is a product review"); + reviewDescription.setName("A review for you"); + reviewDescription.setProductReview(review); + review.getDescriptions().add(reviewDescription); + + productReviewService.create(review); + + } + + private void testCreateRelationShip(Product product) throws Exception { + + MerchantStore store = merchantService.getByCode(MerchantStore.DEFAULT_STORE); + Language en = languageService.getByCode("en"); + Manufacturer oreilley = manufacturerService.getByCode(store, "oreilley"); + ProductType generalType = productTypeService.getProductType(ProductType.GENERAL_TYPE); + + Category tech = categoryService.getByCode(store, "tech"); + + + //create new related product + // PRODUCT 1 + + Product related = new Product(); + related.setProductHeight(new BigDecimal(4)); + related.setProductLength(new BigDecimal(3)); + related.setProductWidth(new BigDecimal(1)); + related.setSku("TB67891"); + related.setManufacturer(oreilley); + related.setType(generalType); + related.setMerchantStore(store); + + // Product description + ProductDescription description = new ProductDescription(); + description.setName("Spring 4 in Action"); + description.setLanguage(en); + description.setProduct(related); + + product.getDescriptions().add(description); + + //add category + product.getCategories().add(tech); + + + + // Availability + ProductAvailability availability = new ProductAvailability(); + availability.setProductDateAvailable(date); + availability.setProductQuantity(200); + availability.setRegion("*"); + availability.setProduct(related);// associate with product + + //productAvailabilityService.create(availability); + related.getAvailabilities().add(availability); + + ProductPrice dprice = new ProductPrice(); + dprice.setDefaultPrice(true); + dprice.setProductPriceAmount(new BigDecimal(39.99)); + dprice.setProductAvailability(availability); + + ProductPriceDescription dpd = new ProductPriceDescription(); + dpd.setName("Base price"); + dpd.setProductPrice(dprice); + dpd.setLanguage(en); + + dprice.getDescriptions().add(dpd); + availability.getPrices().add(dprice); + + related.getAvailabilities().add(availability); + + productService.save(related); + + ProductRelationship relationship = new ProductRelationship(); + + relationship.setActive(true); + relationship.setCode("spring"); + relationship.setProduct(product); + relationship.setRelatedProduct(related); + relationship.setStore(store); + + + //because relationships are nor joined fetched, make sure you query relationships first, then ad to an existing list + //so relationship and review are they only objects not joined fetch when querying a product + //need to do a subsequent query + List relationships = productRelationshipService.listByProduct(product); + + + relationships.add(relationship); + + product.setRelationships(new HashSet(relationships)); + + productService.save(product); + + + } + + + + + +} \ No newline at end of file diff --git a/sm-core/src/test/java/com/salesmanager/test/common/AbstractSalesManagerCoreTestCase.java b/sm-core/src/test/java/com/salesmanager/test/common/AbstractSalesManagerCoreTestCase.java new file mode 100755 index 0000000000..8509e51ec4 --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/common/AbstractSalesManagerCoreTestCase.java @@ -0,0 +1,170 @@ +/** + * This application is maintained by CSTI consulting (www.csticonsulting.com). + * Licensed under LGPL - Feel free to use it and modify it to your needs ! + * + */ +package com.salesmanager.test.common; + +import javax.inject.Inject; + +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.category.CategoryService; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductOptionService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductOptionSetService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductOptionValueService; +import com.salesmanager.core.business.services.catalog.product.availability.ProductAvailabilityService; +import com.salesmanager.core.business.services.catalog.product.image.ProductImageService; +import com.salesmanager.core.business.services.catalog.product.manufacturer.ManufacturerService; +import com.salesmanager.core.business.services.catalog.product.price.ProductPriceService; +import com.salesmanager.core.business.services.catalog.product.relationship.ProductRelationshipService; +import com.salesmanager.core.business.services.catalog.product.review.ProductReviewService; +import com.salesmanager.core.business.services.catalog.product.type.ProductTypeService; +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.customer.attribute.CustomerOptionService; +import com.salesmanager.core.business.services.customer.attribute.CustomerOptionSetService; +import com.salesmanager.core.business.services.customer.attribute.CustomerOptionValueService; +import com.salesmanager.core.business.services.merchant.MerchantStoreService; +import com.salesmanager.core.business.services.order.OrderService; +import com.salesmanager.core.business.services.payments.PaymentService; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.currency.CurrencyService; +import com.salesmanager.core.business.services.reference.init.InitializationDatabase; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.services.reference.zone.ZoneService; +import com.salesmanager.core.business.services.shoppingcart.ShoppingCartService; +import com.salesmanager.core.business.services.system.EmailService; +import com.salesmanager.test.configuration.ConfigurationTest; + + +/** + * @author c.samson + * + */ + +@RunWith(SpringRunner.class) +@SpringBootTest(classes=ConfigurationTest.class) +@Ignore +public class AbstractSalesManagerCoreTestCase { + + private static final String CONTEXT_LOAD_NAME = "TEST"; + + + + protected static String CAD_CURRENCY_CODE = "CAD"; + protected static String USD_CURRENCY_CODE = "USD"; + + protected static String ENGLISH_LANGUAGE_CODE = "en"; + protected static String FRENCH_LANGUAGE_CODE = "fr"; + + @Inject + protected InitializationDatabase initializationDatabase; + + @Inject + protected ProductService productService; + + @Inject + protected PricingService pricingService; + + @Inject + protected ProductPriceService productPriceService; + + @Inject + protected ProductAttributeService productAttributeService; + + @Inject + protected ProductOptionService productOptionService; + + @Inject + protected ProductOptionSetService productOptionSetService; + + @Inject + protected ProductOptionValueService productOptionValueService; + + @Inject + protected ProductAvailabilityService productAvailabilityService; + + @Inject + protected ProductReviewService productReviewService; + + @Inject + protected ProductImageService productImageService; + + @Inject + protected ProductRelationshipService productRelationshipService; + + @Inject + protected CategoryService categoryService; + + @Inject + protected MerchantStoreService merchantService; + + @Inject + protected ProductTypeService productTypeService; + + @Inject + protected LanguageService languageService; + + @Inject + protected CountryService countryService; + + @Inject + protected CurrencyService currencyService; + + @Inject + protected ManufacturerService manufacturerService; + + @Inject + protected ZoneService zoneService; + + @Inject + protected CustomerService customerService; + + @Inject + protected CustomerOptionService customerOptionService; + + @Inject + protected CustomerOptionValueService customerOptionValueService; + + @Inject + protected CustomerOptionSetService customerOptionSetService; + + @Inject + protected OrderService orderService; + + @Inject + protected PaymentService paymentService; + + @Inject + protected ShoppingCartService shoppingCartService; + + @Inject + protected EmailService emailService; + + @Before + public void init() throws ServiceException { + if(initializationDatabase.isEmpty()) { + populate(); + } + + } + + @After + public void close() throws ServiceException { + + } + + private void populate() throws ServiceException { + initializationDatabase.populate(CONTEXT_LOAD_NAME); + } + +} diff --git a/sm-core/src/test/java/com/salesmanager/test/configuration/ConfigurationTest.java b/sm-core/src/test/java/com/salesmanager/test/configuration/ConfigurationTest.java new file mode 100755 index 0000000000..198c353add --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/configuration/ConfigurationTest.java @@ -0,0 +1,20 @@ +package com.salesmanager.test.configuration; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +@Configuration +@EnableAutoConfiguration +@ComponentScan({"com.salesmanager.core.business"}) +@ImportResource("spring/test-shopizer-context.xml") +@EnableJpaRepositories(basePackages = "com.salesmanager.core.business.repositories") +@EntityScan(basePackages = "com.salesmanager.core.model") +public class ConfigurationTest { + + + +} diff --git a/sm-core/src/test/java/com/salesmanager/test/content/ContentFolderTest.java b/sm-core/src/test/java/com/salesmanager/test/content/ContentFolderTest.java new file mode 100644 index 0000000000..bd259d71e7 --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/content/ContentFolderTest.java @@ -0,0 +1,64 @@ +package com.salesmanager.test.content; + +import java.util.Optional; + +import javax.inject.Inject; + +import org.junit.Ignore; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.content.ContentService; +import com.salesmanager.core.model.merchant.MerchantStore; + +/** + * Test content with CMS store logo + * + * @author Carl Samson + * + */ +@Ignore +public class ContentFolderTest extends com.salesmanager.test.common.AbstractSalesManagerCoreTestCase { + + @Inject + private ContentService contentService; + + + @Ignore + public void listImages() { + } + + @Ignore + public void addFolder() { + + MerchantStore store; + try { + store = super.merchantService.getByCode("DEFAULT"); + + String folderName = "newFolder"; + + Optional path = Optional.ofNullable(null); + + //add folder to root + contentService.addFolder(store, path, folderName); + + //add new folder to newFolder + + } catch (ServiceException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + } + + @Ignore + public void listFolders() { + + } + + @Ignore + public void removeFolder() { + + } + +} \ No newline at end of file diff --git a/sm-core/src/test/java/com/salesmanager/test/content/ContentImagesTest.java b/sm-core/src/test/java/com/salesmanager/test/content/ContentImagesTest.java new file mode 100755 index 0000000000..4e137ab94f --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/content/ContentImagesTest.java @@ -0,0 +1,81 @@ +package com.salesmanager.test.content; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import javax.inject.Inject; + +import org.apache.commons.io.IOUtils; +import org.junit.Ignore; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.content.ContentService; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.InputContentFile; +import com.salesmanager.core.model.content.OutputContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; + +/** + * Test content with CMS store logo + * + * @author Carl Samson + * + */ +@Ignore +public class ContentImagesTest extends com.salesmanager.test.common.AbstractSalesManagerCoreTestCase { + + @Inject + private ContentService contentService; + + // @Test + @Ignore + public void createStoreLogo() throws ServiceException, FileNotFoundException, IOException { + + MerchantStore store = merchantService.getByCode(MerchantStore.DEFAULT_STORE); + + final File file1 = new File("C:/doc/Hadoop.jpg"); + + if (!file1.exists() || !file1.canRead()) { + throw new ServiceException("Can't read" + file1.getAbsolutePath()); + } + + byte[] is = IOUtils.toByteArray(new FileInputStream(file1)); + ByteArrayInputStream inputStream = new ByteArrayInputStream(is); + InputContentFile cmsContentImage = new InputContentFile(); + + cmsContentImage.setFileName(file1.getName()); + cmsContentImage.setFile(inputStream); + + // logo as a content + contentService.addLogo(store.getCode(), cmsContentImage); + + store.setStoreLogo(file1.getName()); + merchantService.update(store); + + // query the store + store = merchantService.getByCode(MerchantStore.DEFAULT_STORE); + + // get the logo + String logo = store.getStoreLogo(); + + OutputContentFile image = contentService.getContentFile(store.getCode(), FileContentType.LOGO, logo); + + // print image + OutputStream outputStream = new FileOutputStream("C:/doc/logo-" + image.getFileName()); + + ByteArrayOutputStream baos = image.getFile(); + baos.writeTo(outputStream); + + // remove image + contentService.removeFile(store.getCode(), FileContentType.LOGO, store.getStoreLogo()); + + } + + +} \ No newline at end of file diff --git a/sm-core/src/test/java/com/salesmanager/test/content/StaticContentTest.java b/sm-core/src/test/java/com/salesmanager/test/content/StaticContentTest.java new file mode 100755 index 0000000000..2e365549d9 --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/content/StaticContentTest.java @@ -0,0 +1,92 @@ +package com.salesmanager.test.content; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import javax.inject.Inject; + +import org.apache.commons.io.IOUtils; +import org.junit.Ignore; +import org.junit.Test; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.content.ContentService; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.InputContentFile; +import com.salesmanager.core.model.content.OutputContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; + + + +/** + * Test + * + * - static content files (.js, .pdf etc) + * - static content images (jpg, gig ...) + * @author Carl Samson + * + */ +@Ignore +public class StaticContentTest extends com.salesmanager.test.common.AbstractSalesManagerCoreTestCase { + + + @Inject + private ContentService contentService; + + /** + * Change this path to an existing image path + */ + private final static String IMAGE_FILE = "/Users/carlsamson/Documents/Database.png"; + + private final static String OUTPUT_FOLDER = "/Users/carlsamson/Documents/test/"; + + + @Test + public void createImage() + throws ServiceException, FileNotFoundException, IOException + { + + MerchantStore store = merchantService.getByCode( MerchantStore.DEFAULT_STORE ); + final File file1 = new File( IMAGE_FILE); + + if ( !file1.exists() || !file1.canRead() ) + { + throw new ServiceException( "Can't read" + file1.getAbsolutePath() ); + } + + final byte[] is = IOUtils.toByteArray( new FileInputStream( file1 ) ); + final ByteArrayInputStream inputStream = new ByteArrayInputStream( is ); + final InputContentFile cmsContentImage = new InputContentFile(); + cmsContentImage.setFileName( file1.getName() ); + cmsContentImage.setFile( inputStream ); + cmsContentImage.setFileContentType(FileContentType.IMAGE); + + //Add image + contentService.addContentFile(store.getCode(), cmsContentImage); + + + //get image + OutputContentFile image = contentService.getContentFile(store.getCode(), FileContentType.IMAGE, file1.getName()); + + //print image + OutputStream outputStream = new FileOutputStream (OUTPUT_FOLDER + image.getFileName()); + + ByteArrayOutputStream baos = image.getFile(); + baos.writeTo(outputStream); + + + //remove image + contentService.removeFile(store.getCode(), FileContentType.IMAGE, file1.getName()); + + + + } + + +} \ No newline at end of file diff --git a/sm-core/src/test/java/com/salesmanager/test/customer/CustomerTest.java b/sm-core/src/test/java/com/salesmanager/test/customer/CustomerTest.java new file mode 100755 index 0000000000..6c540783bf --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/customer/CustomerTest.java @@ -0,0 +1,221 @@ +package com.salesmanager.test.customer; + +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.junit.Ignore; +import org.junit.Test; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.common.Billing; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.customer.CustomerGender; +import com.salesmanager.core.model.customer.attribute.CustomerAttribute; +import com.salesmanager.core.model.customer.attribute.CustomerOption; +import com.salesmanager.core.model.customer.attribute.CustomerOptionDescription; +import com.salesmanager.core.model.customer.attribute.CustomerOptionSet; +import com.salesmanager.core.model.customer.attribute.CustomerOptionValue; +import com.salesmanager.core.model.customer.attribute.CustomerOptionValueDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; + + + +@Ignore +public class CustomerTest extends com.salesmanager.test.common.AbstractSalesManagerCoreTestCase { + + @Test + public void createCustomer() throws ServiceException { + + + Language en = languageService.getByCode("en"); + + + MerchantStore store = merchantService.getByCode(MerchantStore.DEFAULT_STORE); + Country country = countryService.getByCode("CA"); + Zone zone = zoneService.getByCode("QC"); + + /** Core customer attributes **/ + Customer customer = new Customer(); + customer.setMerchantStore(store); + customer.setEmailAddress("test@test.com"); + customer.setGender(CustomerGender.M); + + customer.setAnonymous(true); + customer.setCompany("ifactory"); + customer.setDateOfBirth(new Date()); + customer.setNick("My nick"); + customer.setPassword("123456"); + customer.setDefaultLanguage(store.getDefaultLanguage()); + + Delivery delivery = new Delivery(); + delivery.setAddress("Shipping address"); + delivery.setCountry(country); + delivery.setZone(zone); + + + Billing billing = new Billing(); + billing.setFirstName("John"); + billing.setLastName("Bossanova"); + billing.setAddress("Billing address"); + billing.setCountry(country); + billing.setZone(zone); + + customer.setBilling(billing); + customer.setDelivery(delivery); + + customerService.create(customer); + customer = customerService.getById(customer.getId()); + + + //create an option value + CustomerOptionValue yes = new CustomerOptionValue(); + yes.setCode("yes"); + yes.setMerchantStore(store); + CustomerOptionValueDescription yesDescription = new CustomerOptionValueDescription(); + yesDescription.setLanguage(en); + yesDescription.setCustomerOptionValue(yes); + + CustomerOptionValueDescription yes_sir = new CustomerOptionValueDescription(); + yes_sir.setCustomerOptionValue(yes); + yes_sir.setDescription("Yes sir!"); + yes_sir.setName("Yes sir!"); + yes_sir.setLanguage(en); + yes.getDescriptions().add(yes_sir); + + //needs to be saved before using it + customerOptionValueService.create(yes); + + CustomerOptionValue no = new CustomerOptionValue(); + no.setCode("no"); + no.setMerchantStore(store); + CustomerOptionValueDescription noDescription = new CustomerOptionValueDescription(); + noDescription.setLanguage(en); + noDescription.setCustomerOptionValue(no); + + CustomerOptionValueDescription no_sir = new CustomerOptionValueDescription(); + no_sir.setCustomerOptionValue(no); + no_sir.setDescription("Nope!"); + no_sir.setName("Nope!"); + no_sir.setLanguage(en); + no.getDescriptions().add(no_sir); + + //needs to be saved before using it + customerOptionValueService.create(no); + + + //create a customer option to be used + CustomerOption subscribedToMailingList = new CustomerOption(); + subscribedToMailingList.setActive(true); + subscribedToMailingList.setPublicOption(true); + subscribedToMailingList.setCode("subscribedToMailingList"); + subscribedToMailingList.setMerchantStore(store); + + CustomerOptionDescription mailingListDesciption= new CustomerOptionDescription(); + mailingListDesciption.setName("Subscribed to mailing list"); + mailingListDesciption.setDescription("Subscribed to mailing list"); + mailingListDesciption.setLanguage(en); + mailingListDesciption.setCustomerOption(subscribedToMailingList); + + Set mailingListDesciptionList = new HashSet(); + mailingListDesciptionList.add(mailingListDesciption); + subscribedToMailingList.setDescriptions(mailingListDesciptionList); + + customerOptionService.create(subscribedToMailingList); + + + //create a customer option to be used + CustomerOption hasReturnedItems = new CustomerOption(); + hasReturnedItems.setActive(true); + hasReturnedItems.setPublicOption(true); + hasReturnedItems.setCode("hasReturnedItems"); + hasReturnedItems.setMerchantStore(store); + + CustomerOptionDescription hasReturnedItemsDesciption= new CustomerOptionDescription(); + hasReturnedItemsDesciption.setName("Has returned items"); + hasReturnedItemsDesciption.setDescription("Has returned items"); + hasReturnedItemsDesciption.setLanguage(en); + hasReturnedItemsDesciption.setCustomerOption(hasReturnedItems); + + Set hasReturnedItemsList = new HashSet(); + hasReturnedItemsList.add(hasReturnedItemsDesciption); + hasReturnedItems.setDescriptions(hasReturnedItemsList); + + customerOptionService.create(hasReturnedItems); + + subscribedToMailingList.setSortOrder(3); + + customerOptionService.update(subscribedToMailingList); + + //-- + //now create an option set (association of a customer option with possible customer option values) + //-- + + //possible yes + CustomerOptionSet mailingListSetYes = new CustomerOptionSet(); + + mailingListSetYes.setSortOrder(0); + mailingListSetYes.setCustomerOption(subscribedToMailingList); + mailingListSetYes.setCustomerOptionValue(yes); + + customerOptionSetService.create(mailingListSetYes); + + //possible no + CustomerOptionSet mailingListSetNo = new CustomerOptionSet(); + //mailingListSetNo.setPk(mailingListSetNoId); + mailingListSetNo.setSortOrder(1); + mailingListSetNo.setCustomerOption(subscribedToMailingList); + mailingListSetNo.setCustomerOptionValue(no); + + customerOptionSetService.create(mailingListSetNo); + + //possible has returned items + + CustomerOptionSet hasReturnedItemsYes = new CustomerOptionSet(); + hasReturnedItemsYes.setSortOrder(0); + hasReturnedItemsYes.setCustomerOption(hasReturnedItems); + hasReturnedItemsYes.setCustomerOptionValue(yes); + + customerOptionSetService.create(hasReturnedItemsYes); + + + subscribedToMailingList.setSortOrder(2); + customerOptionService.update(subscribedToMailingList); + + CustomerOption option = customerOptionService.getById(subscribedToMailingList.getId()); + + option.setSortOrder(4); + customerOptionService.update(option); + + List optionSetList = customerOptionSetService.listByStore(store, en); + + //Assert.assertEquals(3, optionSetList.size()); + System.out.println("Size of options : " + optionSetList.size()); + + /** + * Now create a customer option attribute + * A customer attribute is a selected customer option set transformed to an + * attribute for a given customer + */ + + CustomerAttribute customerAttributeMailingList = new CustomerAttribute(); + customerAttributeMailingList.setCustomer(customer); + customerAttributeMailingList.setCustomerOption(subscribedToMailingList); + customerAttributeMailingList.setCustomerOptionValue(no); + + customer.getAttributes().add(customerAttributeMailingList); + + customerService.save(customer); + + customerService.delete(customer); + + + + + } +} diff --git a/sm-core/src/test/java/com/salesmanager/test/modules/ModulesTest.java b/sm-core/src/test/java/com/salesmanager/test/modules/ModulesTest.java new file mode 100644 index 0000000000..ba89d2606c --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/modules/ModulesTest.java @@ -0,0 +1,27 @@ +package com.salesmanager.test.modules; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.services.system.ModuleConfigurationService; +import com.salesmanager.core.model.system.IntegrationModule; + +public class ModulesTest extends com.salesmanager.test.common.AbstractSalesManagerCoreTestCase { + + @Autowired + private ModuleConfigurationService moduleConfigurationService = null; + + + @Test + public void testModulesConfigurations() throws Exception { + List modules = moduleConfigurationService.getIntegrationModules(Constants.PAYMENT_MODULES); + + Assert.assertNotNull(modules); + } + + +} diff --git a/sm-core/src/test/java/com/salesmanager/test/order/InvoiceTest.java b/sm-core/src/test/java/com/salesmanager/test/order/InvoiceTest.java new file mode 100755 index 0000000000..2f598b547a --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/order/InvoiceTest.java @@ -0,0 +1,642 @@ +package com.salesmanager.test.order; + +import org.junit.Ignore; + + +/** + * This test has to be completed + * @author c.samson + * + */ +@Ignore +public class InvoiceTest extends com.salesmanager.test.common.AbstractSalesManagerCoreTestCase { +/* + @Inject + ProductPriceUtils priceUtil; + + + @Ignore + public void createInvoice() throws ServiceException { + + + MerchantStore store = merchantService.getByCode(MerchantStore.DEFAULT_STORE); + + //create a product + ProductType generalType = productTypeService.getProductType(ProductType.GENERAL_TYPE); + + Language en = languageService.getByCode("en"); + + + *//** + * 1) Create an order + * + *//* + + //1.1 create a product + + //create an option + ProductOption color = new ProductOption(); + color.setMerchantStore(store); + color.setCode("color"); + color.setProductOptionType("SELECT"); + + ProductOptionDescription colorDescription = new ProductOptionDescription(); + colorDescription.setDescription("Color"); + colorDescription.setName("Color"); + colorDescription.setLanguage(en); + colorDescription.setProductOption(color); + + Set colorDescriptions = new HashSet(); + colorDescriptions.add(colorDescription); + + color.setDescriptions(colorDescriptions); + + productOptionService.create(color); + + //create an option value + ProductOptionValue red = new ProductOptionValue(); + red.setMerchantStore(store); + red.setCode("red"); + + ProductOptionValueDescription redDescription = new ProductOptionValueDescription(); + redDescription.setDescription("Red"); + redDescription.setLanguage(en); + redDescription.setName("Red"); + redDescription.setProductOptionValue(red); + + Set redDescriptions = new HashSet(); + redDescriptions.add(redDescription); + + red.setDescriptions(redDescriptions); + + productOptionValueService.create(red); + + //create a product + Product product = new Product(); + product.setProductHeight(new BigDecimal(4)); + product.setProductLength(new BigDecimal(3)); + product.setProductWidth(new BigDecimal(5)); + product.setProductWeight(new BigDecimal(8)); + product.setSku("TESTSKU"); + product.setType(generalType); + product.setMerchantStore(store); + + // Product description + ProductDescription description = new ProductDescription(); + description.setName("Product 1"); + description.setLanguage(en); + description.setProduct(product); + + product.getDescriptions().add(description); + + + // Availability + ProductAvailability availability = new ProductAvailability(); + availability.setProductDateAvailable(new Date()); + availability.setProductQuantity(100); + availability.setRegion("*"); + availability.setProduct(product);// associate with product + + product.getAvailabilities().add(availability); + + //price + ProductPrice dprice = new ProductPrice(); + dprice.setDefaultPrice(true); + dprice.setProductPriceAmount(new BigDecimal(29.99)); + dprice.setProductAvailability(availability); + + ProductPriceDescription dpd = new ProductPriceDescription(); + dpd.setName("Base price"); + dpd.setProductPrice(dprice); + dpd.setLanguage(en); + + dprice.getDescriptions().add(dpd); + + + //create an attribute + ProductAttribute colorAttribute = new ProductAttribute(); + colorAttribute.setProduct(product); + colorAttribute.setProductAttributePrice(new BigDecimal(5)); + colorAttribute.setProductOption(color); + colorAttribute.setProductOptionValue(red); + + + product.getAttributes().add(colorAttribute); + + productService.createProduct(product); + + + //1.2 create a Customer + Country country = countryService.getByCode("CA"); + Zone zone = zoneService.getByCode("QC"); + + Customer customer = new Customer(); + customer.setMerchantStore(store); + customer.setEmailAddress("test@test.com"); + customer.setGender(CustomerGender.M); + customer.setAnonymous(true); + customer.setCompany("ifactory"); + customer.setDateOfBirth(new Date()); + customer.setNick("My nick"); + customer.setDefaultLanguage(en); + + + Delivery delivery = new Delivery(); + delivery.setAddress("358 Du Languadoc"); + delivery.setCity( "Boucherville" ); + delivery.setCountry(country); +// delivery.setCountryCode(CA_COUNTRY_CODE); + delivery.setFirstName("First" ); + delivery.setLastName("Last" ); + delivery.setPostalCode("J4B-8J9" ); + delivery.setZone(zone); + + Billing billing = new Billing(); + billing.setAddress("358 Du Languadoc"); + billing.setCity("Boucherville"); + billing.setCompany("CSTI Consulting"); + billing.setCountry(country); +// billing.setCountryCode(CA_COUNTRY_CODE); + billing.setFirstName("Carl" ); + billing.setLastName("Samson" ); + billing.setPostalCode("J4B-8J9"); + billing.setZone(zone); + + customer.setBilling(billing); + customer.setDelivery(delivery); + customerService.create(customer); + + Currency currency = currencyService.getByCode(CAD_CURRENCY_CODE); + + //1.3 create an order + OrderStatusHistory orderStatusHistory = new OrderStatusHistory(); + + + Order order = new Order(); + order.setDatePurchased(new Date()); + order.setCurrency(currency); + order.setLastModified(new Date()); + order.setBilling(billing); + + Locale l = Locale.CANADA; + order.setLocale(l); + + + order.setCurrencyValue(new BigDecimal(0.98));//compared to based currency (not necessary) + order.setCustomerId(customer.getId()); + order.setDelivery(delivery); + order.setIpAddress("ipAddress" ); + order.setMerchant(store); + order.setCustomerEmailAddress(customer.getEmailAddress()); + order.setOrderDateFinished(new Date());//committed date + + orderStatusHistory.setComments("We received your order"); + orderStatusHistory.setCustomerNotified(1); + orderStatusHistory.setStatus(OrderStatus.ORDERED); + orderStatusHistory.setDateAdded(new Date() ); + orderStatusHistory.setOrder(order); + order.getOrderHistory().add( orderStatusHistory ); + + + order.setPaymentType(PaymentType.PAYPAL); + order.setPaymentModuleCode("paypal"); + order.setStatus( OrderStatus.DELIVERED); + order.setTotal(new BigDecimal(23.99)); + + + //OrderProductDownload - Digital download + OrderProductDownload orderProductDownload = new OrderProductDownload(); + orderProductDownload.setDownloadCount(1); + orderProductDownload.setMaxdays(31); + orderProductDownload.setOrderProductFilename("Your digital file name"); + + //OrderProductPrice + OrderProductPrice oproductprice = new OrderProductPrice(); + oproductprice.setDefaultPrice(true); + oproductprice.setProductPrice(new BigDecimal(19.99) ); + oproductprice.setProductPriceCode("baseprice" ); + oproductprice.setProductPriceName("Base Price" ); + + //OrderProduct + OrderProduct oproduct = new OrderProduct(); + oproduct.getDownloads().add( orderProductDownload); + oproduct.setOneTimeCharge( new BigDecimal(19.99) ); + oproduct.setOrder(order); + oproduct.setProductName( "Product name" ); + oproduct.setProductQuantity(2); + oproduct.setSku("TB12345" ); + oproduct.getPrices().add(oproductprice ) ; + + + //an attribute to the OrderProduct + OrderProductAttribute orderAttribute = new OrderProductAttribute(); + orderAttribute.setOrderProduct(oproduct); + orderAttribute.setProductAttributeName(colorDescription.getName()); + orderAttribute.setProductAttributeValueName(redDescription.getName()); + orderAttribute.setProductOptionId(color.getId()); + orderAttribute.setProductOptionValueId(red.getId()); + orderAttribute.setProductAttributePrice(colorAttribute.getProductAttributePrice()); + + Set orderAttributes = new HashSet(); + orderAttributes.add(orderAttribute); + + oproduct.setOrderAttributes(orderAttributes); + + oproductprice.setOrderProduct(oproduct); + orderProductDownload.setOrderProduct(oproduct); + order.getOrderProducts().add(oproduct); + + + //product #2 + OrderProductPrice oproductprice2 = new OrderProductPrice(); + oproductprice2.setDefaultPrice(true); + oproductprice2.setProductPrice(new BigDecimal(9.99) ); + oproductprice2.setProductPriceCode("baseprice" ); + oproductprice2.setProductPriceName("Base Price" ); + + //OrderProduct + OrderProduct oproduct2 = new OrderProduct(); + oproduct2.setOneTimeCharge( new BigDecimal(9.99) ); + oproduct2.setOrder(order); + oproduct2.setProductName( "Additional item name" ); + oproduct2.setProductQuantity(1); + oproduct2.setSku("TB12346" ); + oproduct2.getPrices().add(oproductprice2 ) ; + + oproductprice2.setOrderProduct(oproduct2); + order.getOrderProducts().add(oproduct2); + + + + + + //requires + //OrderProduct + //OrderProductPrice + //OrderTotal + + + + //OrderTotal + OrderTotal subtotal = new OrderTotal(); + subtotal.setModule("summary" ); + subtotal.setSortOrder(0); + subtotal.setText("Summary" ); + subtotal.setTitle("Summary" ); + subtotal.setValue(new BigDecimal(19.99 ) ); + subtotal.setOrder(order); + + order.getOrderTotal().add(subtotal); + + OrderTotal tax = new OrderTotal(); + tax.setModule("tax" ); + tax.setSortOrder(1); + tax.setText("Tax" ); + tax.setTitle("Tax" ); + tax.setValue(new BigDecimal(4) ); + tax.setOrder(order); + + order.getOrderTotal().add(tax); + + OrderTotal total = new OrderTotal(); + total.setModule("total" ); + total.setSortOrder(2); + total.setText("Total" ); + total.setTitle("Total" ); + total.setValue(new BigDecimal(23.99) ); + total.setOrder(order); + + order.getOrderTotal().add(total); + + orderService.create(order); + Assert.assertTrue(orderService.count() == 1); + + Locale locale = Locale.ENGLISH; + + + order = orderService.getById(order.getId()); + + *//** + * 2 Create an invoice + *//* + try { + URL resource = getClass().getResource("/templates/invoice/invoice.ods"); + File file = new File(resource.toURI()); + //File file = new File("templates/invoice/invoice.ods"); + + Sheet sheet = SpreadSheet.createFromFile(file).getSheet(0); + + + //Store name + sheet.setValueAt(store.getStorename(), 0, 0); + + store.setStoreaddress("2001 zoo avenue"); + store.setCurrencyFormatNational(true);//use $ instead of USD + + + //Address + //count store address cell + int storeAddressCell = 2; + //if(!StringUtils.isBlank(store.getStoreaddress())) { + // sheet.setValueAt(store.getStoreaddress(), 0, storeAddressCell); + // storeAddressCell ++; + //} + + //3 + StringBuilder storeAddress = null; + if(!StringUtils.isBlank(store.getStoreaddress())) { + storeAddress = new StringBuilder(); + storeAddress.append(store.getStoreaddress()); + } + if(!StringUtils.isBlank(store.getStorecity())) { + if(storeAddress==null) { + storeAddress = new StringBuilder(); + } else { + storeAddress.append(", "); + } + storeAddress.append(store.getStorecity()); + } + if(storeAddress!=null) { + sheet.setValueAt(storeAddress.toString(), 0, storeAddressCell); + storeAddressCell ++; + } + + //4 + StringBuilder storeProvince = null; + if(store.getZone()!=null) { + storeProvince = new StringBuilder(); + List zones = zoneService.getZones(store.getCountry(), en); + for(Zone z : zones) { + if(z.getCode().equals(store.getZone().getCode())) { + storeProvince.append(store.getZone().getName()); + break; + } + } + + } else { + if(!StringUtils.isBlank(store.getStorestateprovince())) { + storeProvince = new StringBuilder(); + storeProvince.append(store.getStorestateprovince()); + } + } + if(store.getCountry()!=null) { + if(storeProvince==null) { + storeProvince = new StringBuilder(); + } else { + storeProvince.append(", "); + } + Map countries = countryService.getCountriesMap(en); + Country c = countries.get(store.getCountry().getIsoCode()); + if(c!=null) { + storeProvince.append(c.getName()); + } else { + storeProvince.append(store.getCountry().getIsoCode()); + } + + } + if(storeProvince!=null) { + sheet.setValueAt(storeProvince.toString(), 0, storeAddressCell); + storeAddressCell ++; + } + + //5 + if(!StringUtils.isBlank(store.getStorepostalcode())) { + sheet.setValueAt(store.getStorepostalcode(), 0, storeAddressCell); + storeAddressCell ++; + } + + //6 + if(!StringUtils.isBlank(store.getStorephone())) { + sheet.setValueAt(store.getStorephone(), 0, storeAddressCell); + } + + //delete address blank lines + for(int i = storeAddressCell; i<5; i++) { + sheet.setValueAt("", 0, i); + } + + //invoice date + SimpleDateFormat format = new SimpleDateFormat(Constants.DEFAULT_DATE_FORMAT); + sheet.setValueAt(format.format(order.getDatePurchased()), 3, 2); + + //invoice number + sheet.setValueAt(order.getId(), 3, 3); + + //bill to + //count bill to address cell + int billToCell = 8; + if(!StringUtils.isBlank(customer.getBilling().getFirstName())) { + sheet.setValueAt(customer.getBilling().getFirstName() + " " + customer.getBilling().getLastName(), 0, billToCell); + billToCell ++; + } + + //9 + if(!StringUtils.isBlank(customer.getBilling().getCompany())) { + sheet.setValueAt(customer.getBilling().getCompany(), 0, billToCell); + billToCell ++; + } + + //10 + StringBuilder billToAddress = null; + if(!StringUtils.isBlank(customer.getBilling().getAddress())) { + billToAddress = new StringBuilder(); + billToAddress.append(customer.getBilling().getAddress()); + } + if(!StringUtils.isBlank(customer.getBilling().getCity())) { + if(billToAddress==null) { + billToAddress = new StringBuilder(); + } else { + billToAddress.append(", "); + } + billToAddress.append(customer.getBilling().getCity()); + } + if(billToAddress!=null) { + sheet.setValueAt(billToAddress.toString(), 0, billToCell); + billToCell ++; + } + + //11 + StringBuilder billToProvince = null; + if(customer.getBilling().getZone()!=null) { + billToProvince = new StringBuilder(); + List zones = zoneService.getZones(customer.getBilling().getCountry(), en); + for(Zone z : zones) { + if(z.getCode().equals(customer.getBilling().getZone().getCode())) { + billToProvince.append(customer.getBilling().getZone().getName()); + break; + } + } + + } else { + if(!StringUtils.isBlank(customer.getBilling().getState())) { + billToProvince = new StringBuilder(); + billToProvince.append(customer.getBilling().getState()); + } + } + if(customer.getBilling().getCountry()!=null) { + if(billToProvince==null) { + billToProvince = new StringBuilder(); + } else { + billToProvince.append(", "); + } + Map countries = countryService.getCountriesMap(en); + Country c = countries.get(customer.getBilling().getCountry().getIsoCode()); + if(c!=null) { + billToProvince.append(c.getName()); + } else { + billToProvince.append(customer.getBilling().getCountry().getIsoCode()); + } + + } + if(billToProvince!=null) { + sheet.setValueAt(billToProvince.toString(), 0, billToCell); + billToCell ++; + } + + //12 + if(!StringUtils.isBlank(customer.getBilling().getPostalCode())) { + sheet.setValueAt(customer.getBilling().getPostalCode(), 0, billToCell); + billToCell ++; + } + + //13 + if(!StringUtils.isBlank(customer.getBilling().getTelephone())) { + sheet.setValueAt(customer.getBilling().getTelephone(), 0, billToCell); + } + + //delete address blank lines + for(int i = billToCell; i<13; i++) { + sheet.setValueAt("", 0, i); + } + + //products + Set orderProducts = order.getOrderProducts(); + int productCell = 16; + for(OrderProduct orderProduct : orderProducts) { + + //product name + String pName = orderProduct.getProductName(); + Set oAttributes = orderProduct.getOrderAttributes(); + StringBuilder attributeName = null; + for(OrderProductAttribute oProductAttribute : oAttributes) { + if(attributeName == null) { + attributeName = new StringBuilder(); + attributeName.append("["); + } else { + attributeName.append(", "); + } + attributeName.append(oProductAttribute.getProductAttributeName()) + .append(": ") + .append(oProductAttribute.getProductAttributeValueName()); + + } + + + StringBuilder productName = new StringBuilder(); + productName.append(pName); + + if(attributeName!=null) { + attributeName.append("]"); + productName.append(" ").append(attributeName.toString()); + } + + + + + sheet.setValueAt(productName.toString(), 0, productCell); + + int quantity = orderProduct.getProductQuantity(); + sheet.setValueAt(quantity, 1, productCell); + String amount = priceUtil.getStoreFormatedAmountWithCurrency(store, orderProduct.getOneTimeCharge()); + sheet.setValueAt(amount, 2, productCell); + String t = priceUtil.getStoreFormatedAmountWithCurrency(store, priceUtil.getOrderProductTotalPrice(store, orderProduct)); + sheet.setValueAt(t, 3, productCell); + + productCell++; + + } + + //print totals + productCell++; + Set totals = order.getOrderTotal(); + for(OrderTotal orderTotal : totals) { + + String totalName = orderTotal.getText(); + String totalValue = priceUtil.getStoreFormatedAmountWithCurrency(store,orderTotal.getValue()); + sheet.setValueAt(totalName, 2, productCell); + sheet.setValueAt(totalValue, 3, productCell); + productCell++; + } + + //sheet.getCellAt(0, 0).setImage(arg0) + //sheet.getCellAt(0, 0).setStyleName(arg0) + //sheet.getCellAt(0, 0).getStyle(). + + + + File outputFile = new File(order.getId() + "_invoice.ods"); + OOUtils.open(sheet.getSpreadSheet().saveAs(outputFile)); + + + final OpenDocument doc = new OpenDocument(); + doc.loadFrom(order.getId() + "_invoice.ods"); + + // Open the PDF document + Document document = new Document(PageSize.A4); + File outFile = new File("invoice.pdf"); + + PdfDocument pdf = new PdfDocument(); + + document.addDocListener(pdf); + + FileOutputStream fileOutputStream = new FileOutputStream(outFile); + PdfWriter writer = PdfWriter.getInstance(pdf, fileOutputStream); + pdf.addWriter(writer); + + document.open(); + + // Create a template and a Graphics2D object + Rectangle pageSize = document.getPageSize(); + int w = (int) (pageSize.getWidth() * 0.9); + int h = (int) (pageSize.getHeight() * 0.95); + PdfContentByte cb = writer.getDirectContent(); + PdfTemplate tp = cb.createTemplate(w, h); + + Graphics2D g2 = tp.createPrinterGraphics(w, h, null); + // If you want to prevent copy/paste, you can use + // g2 = tp.createGraphicsShapes(w, h, true, 0.9f); + + tp.setWidth(w); + tp.setHeight(h); + + // Configure the renderer + ODTRenderer renderer = new ODTRenderer(doc); + renderer.setIgnoreMargins(true); + renderer.setPaintMaxResolution(true); + + // Scale the renderer to fit width + renderer.setResizeFactor(renderer.getPrintWidth() / w); + // Render + renderer.paintComponent(g2); + g2.dispose(); + + // Add our spreadsheet in the middle of the page + float offsetX = (pageSize.getWidth() - w) / 2; + float offsetY = (pageSize.getHeight() - h) / 2; + cb.addTemplate(tp, offsetX, offsetY); + // Close the PDF document + document.close(); + + outputFile.delete();//remove temp file + + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + }*/ + + + +} \ No newline at end of file diff --git a/sm-core/src/test/java/com/salesmanager/test/order/OrderTest.java b/sm-core/src/test/java/com/salesmanager/test/order/OrderTest.java new file mode 100755 index 0000000000..cd9049ebbc --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/order/OrderTest.java @@ -0,0 +1,401 @@ +package com.salesmanager.test.order; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.category.CategoryDescription; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionType; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValueDescription; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.description.ProductDescription; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.catalog.product.manufacturer.ManufacturerDescription; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPriceDescription; +import com.salesmanager.core.model.catalog.product.price.ProductPriceType; +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.common.Billing; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.customer.CustomerGender; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.order.OrderCriteria; +import com.salesmanager.core.model.order.OrderList; +import com.salesmanager.core.model.order.OrderTotal; +import com.salesmanager.core.model.order.orderproduct.OrderProduct; +import com.salesmanager.core.model.order.orderproduct.OrderProductAttribute; +import com.salesmanager.core.model.order.orderproduct.OrderProductPrice; +import com.salesmanager.core.model.order.orderstatus.OrderStatus; +import com.salesmanager.core.model.order.orderstatus.OrderStatusHistory; +import com.salesmanager.core.model.order.payment.CreditCard; +import com.salesmanager.core.model.payments.CreditCardType; +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.currency.Currency; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + + +@Ignore +public class OrderTest extends com.salesmanager.test.common.AbstractSalesManagerCoreTestCase { + + + + + @Test + public void getMerchantOrders() throws ServiceException { + + + + Currency currency = currencyService.getByCode(USD_CURRENCY_CODE); + Country country = countryService.getByCode("US"); + Zone zone = zoneService.getByCode("VT"); + Language en = languageService.getByCode("en"); + + MerchantStore merchant = merchantService.getByCode( MerchantStore.DEFAULT_STORE ); + + /** Create a customer **/ + Customer customer = new Customer(); + customer.setMerchantStore(merchant); + customer.setDefaultLanguage(en); + customer.setEmailAddress("email@email.com"); + customer.setPassword("-1999"); + customer.setNick("My New nick"); + customer.setCompany(" Apple"); + customer.setGender(CustomerGender.M); + customer.setDateOfBirth(new Date()); + + Billing billing = new Billing(); + billing.setAddress("Billing address"); + billing.setCity("Billing city"); + billing.setCompany("Billing company"); + billing.setCountry(country); + billing.setFirstName("Carl"); + billing.setLastName("Samson"); + billing.setPostalCode("Billing postal code"); + billing.setState("Billing state"); + billing.setZone(zone); + + Delivery delivery = new Delivery(); + delivery.setAddress("Shipping address"); + delivery.setCountry(country); + delivery.setZone(zone); + + customer.setBilling(billing); + customer.setDelivery(delivery); + + customerService.create(customer); + + + //create a product with attributes + + /** CATALOG CREATION **/ + + ProductType generalType = productTypeService.getProductType(ProductType.GENERAL_TYPE); + + /** + * Create the category + */ + Category shirts = new Category(); + shirts.setMerchantStore(merchant); + shirts.setCode("shirts"); + + CategoryDescription shirtsEnglishDescription = new CategoryDescription(); + shirtsEnglishDescription.setName("Shirts"); + shirtsEnglishDescription.setCategory(shirts); + shirtsEnglishDescription.setLanguage(en); + + Set descriptions = new HashSet(); + descriptions.add(shirtsEnglishDescription); + + + shirts.setDescriptions(descriptions); + categoryService.create(shirts); + + + /** + * Create a manufacturer + */ + Manufacturer addidas = new Manufacturer(); + addidas.setMerchantStore(merchant); + addidas.setCode("addidas"); + + ManufacturerDescription addidasDesc = new ManufacturerDescription(); + addidasDesc.setLanguage(en); + addidasDesc.setManufacturer(addidas); + addidasDesc.setName("Addidas"); + addidas.getDescriptions().add(addidasDesc); + + manufacturerService.create(addidas); + + /** + * Create an option + */ + ProductOption option = new ProductOption(); + option.setMerchantStore(merchant); + option.setCode("color"); + option.setProductOptionType(ProductOptionType.Radio.name()); + + ProductOptionDescription optionDescription = new ProductOptionDescription(); + optionDescription.setLanguage(en); + optionDescription.setName("Color"); + optionDescription.setDescription("Item color"); + optionDescription.setProductOption(option); + + option.getDescriptions().add(optionDescription); + + productOptionService.saveOrUpdate(option); + + + /** first option value **/ + ProductOptionValue white = new ProductOptionValue(); + white.setMerchantStore(merchant); + white.setCode("white"); + + ProductOptionValueDescription whiteDescription = new ProductOptionValueDescription(); + whiteDescription.setLanguage(en); + whiteDescription.setName("White"); + whiteDescription.setDescription("White color"); + whiteDescription.setProductOptionValue(white); + + white.getDescriptions().add(whiteDescription); + + productOptionValueService.saveOrUpdate(white); + + + ProductOptionValue black = new ProductOptionValue(); + black.setMerchantStore(merchant); + black.setCode("black"); + + /** second option value **/ + ProductOptionValueDescription blackDesc = new ProductOptionValueDescription(); + blackDesc.setLanguage(en); + blackDesc.setName("Black"); + blackDesc.setDescription("Black color"); + blackDesc.setProductOptionValue(black); + + black.getDescriptions().add(blackDesc); + + productOptionValueService.saveOrUpdate(black); + + + /** + * Create a complex product + */ + Product product = new Product(); + product.setProductHeight(new BigDecimal(4)); + product.setProductLength(new BigDecimal(3)); + product.setProductWidth(new BigDecimal(1)); + product.setSku("TB12345"); + product.setManufacturer(addidas); + product.setType(generalType); + product.setMerchantStore(merchant); + + // Product description + ProductDescription description = new ProductDescription(); + description.setName("Short sleeves shirt"); + description.setLanguage(en); + description.setProduct(product); + + product.getDescriptions().add(description); + product.getCategories().add(shirts); + + + //availability + ProductAvailability availability = new ProductAvailability(); + availability.setProductDateAvailable(new Date()); + availability.setProductQuantity(100); + availability.setRegion("*"); + availability.setProduct(product);// associate with product + + //price + ProductPrice dprice = new ProductPrice(); + dprice.setDefaultPrice(true); + dprice.setProductPriceAmount(new BigDecimal(29.99)); + dprice.setProductAvailability(availability); + + + + ProductPriceDescription dpd = new ProductPriceDescription(); + dpd.setName("Base price"); + dpd.setProductPrice(dprice); + dpd.setLanguage(en); + + dprice.getDescriptions().add(dpd); + availability.getPrices().add(dprice); + product.getAvailabilities().add(availability); + + + //attributes + //white + ProductAttribute whiteAttribute = new ProductAttribute(); + whiteAttribute.setProduct(product); + whiteAttribute.setProductOption(option); + whiteAttribute.setAttributeDefault(true); + whiteAttribute.setProductAttributePrice(new BigDecimal(0));//no price variation + whiteAttribute.setProductAttributeWeight(new BigDecimal(0));//no weight variation + whiteAttribute.setProductOption(option); + whiteAttribute.setProductOptionValue(white); + + product.getAttributes().add(whiteAttribute); + //black + ProductAttribute blackAttribute = new ProductAttribute(); + blackAttribute.setProduct(product); + blackAttribute.setProductOption(option); + blackAttribute.setProductAttributePrice(new BigDecimal(5));//5 + dollars + blackAttribute.setProductAttributeWeight(new BigDecimal(0));//no weight variation + blackAttribute.setProductOption(option); + blackAttribute.setProductOptionValue(black); + + product.getAttributes().add(blackAttribute); + + productService.saveProduct(product); + + + + + /** Create an order **/ + Order order = new Order(); + + + + /** payment details **/ + CreditCard creditCard = new CreditCard(); + creditCard.setCardType(CreditCardType.VISA); + + creditCard.setCcCvv("123"); + creditCard.setCcExpires("12/30/2020" ); + creditCard.setCcNumber( "123456789"); + creditCard.setCcOwner("ccOwner" ); + order.setCreditCard(creditCard); + + /** order core attributes **/ + order.setDatePurchased(new Date()); + order.setCurrency(currency); + order.setMerchant(merchant); + order.setLastModified(new Date()); + order.setCurrencyValue(new BigDecimal(1));//no price variation because of the currency + order.setCustomerId(1L); + order.setDelivery(delivery); + order.setIpAddress("ipAddress" ); + order.setMerchant(merchant); + order.setOrderDateFinished(new Date()); + + order.setPaymentType(PaymentType.CREDITCARD); + order.setPaymentModuleCode("payment Module Code"); + order.setShippingModuleCode("UPS" ); + order.setStatus( OrderStatus.ORDERED); + order.setCustomerAgreement(true); + order.setConfirmedAddress(true); + order.setTotal(dprice.getProductPriceAmount()); + order.setCustomerEmailAddress(customer.getEmailAddress()); + + order.setBilling(billing); + order.setDelivery(delivery); + + + /** ORDER PRODUCT **/ + + //OrderProduct + OrderProduct oproduct = new OrderProduct(); + oproduct.setDownloads(null); + oproduct.setOneTimeCharge(dprice.getProductPriceAmount()); + oproduct.setOrder(order); + oproduct.setProductName( description.getName() ); + oproduct.setProductQuantity(1); + oproduct.setSku(product.getSku()); + + //set order product price + OrderProductPrice orderProductPrice = new OrderProductPrice(); + orderProductPrice.setDefaultPrice(true);//default price (same as default product price) + orderProductPrice.setOrderProduct(oproduct); + orderProductPrice.setProductPrice(dprice.getProductPriceAmount()); + orderProductPrice.setProductPriceCode(ProductPriceType.ONE_TIME.name()); + + + oproduct.getPrices().add(orderProductPrice); + + //order product attribute + + OrderProductAttribute orderProductAttribute = new OrderProductAttribute(); + orderProductAttribute.setOrderProduct(oproduct); + orderProductAttribute.setProductAttributePrice(new BigDecimal("0.00"));//no extra charge + orderProductAttribute.setProductAttributeName(whiteDescription.getName()); + orderProductAttribute.setProductOptionId(option.getId()); + orderProductAttribute.setProductOptionValueId(white.getId()); + + oproduct.getOrderAttributes().add(orderProductAttribute); + + order.getOrderProducts().add(oproduct); + + /** ORDER TOTAL **/ + + OrderTotal subTotal = new OrderTotal(); + subTotal.setOrder(order); + subTotal.setOrderTotalCode(Constants.OT_SUBTOTAL_MODULE_CODE); + subTotal.setSortOrder(0); + subTotal.setTitle("Sub Total"); + subTotal.setValue(dprice.getProductPriceAmount()); + + order.getOrderTotal().add(subTotal); + + + OrderTotal total = new OrderTotal(); + total.setOrder(order); + total.setOrderTotalCode(Constants.OT_TOTAL_MODULE_CODE); + total.setSortOrder(1); + total.setTitle("Total"); + total.setValue(dprice.getProductPriceAmount()); + + order.getOrderTotal().add(total); + + + + + /** ORDER HISTORY **/ + + //create a log entry in order history + OrderStatusHistory history = new OrderStatusHistory(); + history.setOrder(order); + history.setDateAdded(new Date()); + history.setStatus(OrderStatus.ORDERED); + history.setComments("We received your order"); + + order.getOrderHistory().add(history); + + /** CREATE ORDER **/ + + orderService.create(order); + + + /** SEARCH ORDERS **/ + + OrderCriteria criteria = new OrderCriteria(); + criteria.setStartIndex(0); + criteria.setMaxCount(10); + + OrderList ordserList = orderService.listByStore(merchant, criteria); + + + Assert.assertNotNull(ordserList); + Assert.assertNotNull("Merchant Orders are null.", ordserList.getOrders()); + Assert.assertTrue("Merchant Orders count is not one." , (ordserList.getOrders() != null && ordserList.getOrders().size() == 1) ); + } + + + +} \ No newline at end of file diff --git a/sm-core/src/test/java/com/salesmanager/test/references/ReferencesTest.java b/sm-core/src/test/java/com/salesmanager/test/references/ReferencesTest.java new file mode 100755 index 0000000000..77a336aefb --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/references/ReferencesTest.java @@ -0,0 +1,85 @@ +package com.salesmanager.test.references; + +import java.util.List; + +import javax.inject.Inject; + +import org.junit.Ignore; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.country.CountryDescription; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.test.configuration.ConfigurationTest; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest (classes = {ConfigurationTest.class}) +@Ignore +public class ReferencesTest { + + + + @Inject + LanguageService languageService; + + @Inject + CountryService countryService; + + //@Test + @Ignore + public void testReferences() throws ServiceException { + + Language en = new Language(); + en.setCode("en"); + en.setSortOrder(0); + + languageService.save(en); + + Language fr = new Language(); + fr.setCode("fr"); + fr.setSortOrder(0); + + languageService.save(fr); + + + List langs = languageService.getLanguages(); + + System.out.println("Language size " + langs.size()); + + Country us = new Country(); + us.setIsoCode("US"); + + CountryDescription us_en = new CountryDescription(); + us_en.setLanguage(en); + us_en.setCountry(us); + us_en.setName("United States"); + + us.getDescriptions().add(us_en); + + CountryDescription us_fr = new CountryDescription(); + us_fr.setLanguage(fr); + us_fr.setCountry(us); + us_fr.setName("Etats Unis"); + + us.getDescriptions().add(us_fr); + + countryService.save(us); + + Country c = countryService.getByCode("US"); + + System.out.println(c.getId()); + + + + System.out.println("***********Done**************"); + + + + } + +} diff --git a/sm-core/src/test/java/com/salesmanager/test/shipping/ShippingDistanceProcessorTest.java b/sm-core/src/test/java/com/salesmanager/test/shipping/ShippingDistanceProcessorTest.java new file mode 100644 index 0000000000..b99dc72202 --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/shipping/ShippingDistanceProcessorTest.java @@ -0,0 +1,55 @@ +package com.salesmanager.test.shipping; + +import javax.inject.Inject; + +import org.junit.Ignore; + +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.core.model.shipping.ShippingOrigin; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.modules.integration.shipping.model.ShippingQuotePrePostProcessModule; + +@Ignore +public class ShippingDistanceProcessorTest { + + @Inject + ShippingQuotePrePostProcessModule shippingDecisionTablePreProcessor; + + @Ignore + public void testDistance() throws Exception { + + ShippingQuote shippingQuote = new ShippingQuote(); + + Delivery delivery = new Delivery(); + delivery.setAddress("2055 Peel Street"); + delivery.setCity("Montreal"); + delivery.setPostalCode("H3A 1V4"); + + Country country = new Country(); + country.setIsoCode("CA"); + country.setName("Canada"); + delivery.setCountry(country); + + Zone zone = new Zone(); + zone.setCode("QC"); + zone.setName("Quebec"); + + delivery.setZone(zone); + + ShippingOrigin origin = new ShippingOrigin(); + origin.setAddress("7070, avenue Henri-Julien"); + origin.setCity("Montreal"); + origin.setPostalCode("H2S 3S3"); + origin.setZone(zone); + origin.setCountry(country); + + //shippingDecisionTablePreProcessor.prePostProcessShippingQuotes(shippingQuote, null, null, delivery, origin, null, null, null, null, null, Locale.CANADA); + + System.out.println(delivery.getLatitude()); + System.out.println(delivery.getLongitude()); + //System.out.println(shippingQuote.getQuoteInformations().get(Constants.DISTANCE_KEY)); + + } +} diff --git a/sm-core/src/test/java/com/salesmanager/test/shipping/ShippingMethodDecisionTest.java b/sm-core/src/test/java/com/salesmanager/test/shipping/ShippingMethodDecisionTest.java new file mode 100755 index 0000000000..b75b3a8449 --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/shipping/ShippingMethodDecisionTest.java @@ -0,0 +1,88 @@ +package com.salesmanager.test.shipping; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import javax.inject.Inject; + +import org.junit.Ignore; +import org.junit.Test; + +import com.salesmanager.core.business.modules.integration.shipping.impl.ShippingDecisionPreProcessorImpl; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.core.model.shipping.PackageDetails; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.model.system.IntegrationModule; + + + +@Ignore +public class ShippingMethodDecisionTest extends com.salesmanager.test.common.AbstractSalesManagerCoreTestCase { + + @Inject + ShippingDecisionPreProcessorImpl shippingMethodDecisionProcess; + + @Test + @Ignore + public void validateShippingMethod() throws Exception { + + ShippingQuote quote = new ShippingQuote(); + PackageDetails pDetail = new PackageDetails(); + pDetail.setShippingHeight(20); + pDetail.setShippingLength(10); + pDetail.setShippingWeight(70); + pDetail.setShippingWidth(78); + List details = new ArrayList(); + details.add(pDetail); + + Delivery delivery = new Delivery(); + delivery.setAddress("358 Du Languedoc"); + delivery.setCity("Boucherville"); + delivery.setPostalCode("J4B 8J9"); + + Country country = new Country(); + country.setIsoCode("CA"); + country.setName("Canada"); + + //country.setIsoCode("US"); + //country.setName("United States"); + + delivery.setCountry(country); + + Zone zone = new Zone(); + zone.setCode("QC"); + zone.setName("Quebec"); + + //zone.setCode("NY"); + //zone.setName("New York"); + + delivery.setZone(zone); + + IntegrationModule currentModule = new IntegrationModule(); + currentModule.setCode("canadapost"); + quote.setCurrentShippingModule(currentModule); + quote.setShippingModuleCode(currentModule.getCode()); + + IntegrationModule canadapost = new IntegrationModule(); + canadapost.setCode("canadapost"); + + IntegrationModule ups = new IntegrationModule(); + ups.setCode("ups"); + + IntegrationModule inhouse = new IntegrationModule(); + inhouse.setCode("customQuotesRules"); + + List allModules = new ArrayList(); + allModules.add(canadapost); + allModules.add(ups); + allModules.add(inhouse); + + shippingMethodDecisionProcess.prePostProcessShippingQuotes(quote, details, null, delivery, null, null, null, currentModule, null, allModules, Locale.CANADA); + + System.out.println("Done : " + quote.getCurrentShippingModule()!=null ? quote.getCurrentShippingModule().getCode() : currentModule.getCode()); + + } +} diff --git a/sm-core/src/test/java/com/salesmanager/test/shipping/ShippingQuoteByWeightTest.java b/sm-core/src/test/java/com/salesmanager/test/shipping/ShippingQuoteByWeightTest.java new file mode 100755 index 0000000000..5e8feaeef4 --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/shipping/ShippingQuoteByWeightTest.java @@ -0,0 +1,268 @@ +package com.salesmanager.test.shipping; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Set; + +import javax.inject.Inject; + +import org.junit.Ignore; +import org.springframework.util.Assert; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.services.shipping.ShippingService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.description.ProductDescription; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPriceDescription; +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.common.Billing; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.customer.CustomerGender; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.core.model.shipping.ShippingBasisType; +import com.salesmanager.core.model.shipping.ShippingConfiguration; +import com.salesmanager.core.model.shipping.ShippingPackageType; +import com.salesmanager.core.model.shipping.ShippingProduct; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.model.shipping.ShippingType; +import com.salesmanager.core.model.system.Environment; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.modules.integration.shipping.model.CustomShippingQuoteWeightItem; +import com.salesmanager.core.modules.integration.shipping.model.CustomShippingQuotesConfiguration; +import com.salesmanager.core.modules.integration.shipping.model.CustomShippingQuotesRegion; + +@Ignore +public class ShippingQuoteByWeightTest extends com.salesmanager.test.common.AbstractSalesManagerCoreTestCase { + + private static final Date date = new Date(System.currentTimeMillis()); + + @Inject + private ShippingService shippingService; + + @Inject + private LanguageService languageService; + + + + + @Ignore + //@Test + public void testGetCustomShippingQuotesByWeight() throws ServiceException { + + Language en = languageService.getByCode("en"); + Country country = countryService.getByCode("CA"); + Zone zone = zoneService.getByCode("QC"); + + MerchantStore store = merchantService.getByCode(MerchantStore.DEFAULT_STORE); + ProductType generalType = productTypeService.getProductType(ProductType.GENERAL_TYPE); + + //set valid store postal code + store.setStorepostalcode("J4B-9J9"); + + Product product = new Product(); + product.setProductHeight(new BigDecimal(4)); + product.setProductLength(new BigDecimal(3)); + product.setProductWidth(new BigDecimal(5)); + product.setProductWeight(new BigDecimal(8)); + product.setSku("TESTSKU"); + product.setType(generalType); + product.setMerchantStore(store); + + // Product description + ProductDescription description = new ProductDescription(); + description.setName("Product 1"); + description.setLanguage(en); + description.setProduct(product); + + product.getDescriptions().add(description); + + productService.saveProduct(product); + //productService.saveOrUpdate(product); + + + // Availability + ProductAvailability availability = new ProductAvailability(); + availability.setProductDateAvailable(new Date()); + availability.setProductQuantity(100); + availability.setRegion("*"); + availability.setProduct(product);// associate with product + + product.getAvailabilities().add(availability); + + productAvailabilityService.create(availability); + + ProductPrice dprice = new ProductPrice(); + dprice.setDefaultPrice(true); + dprice.setProductPriceAmount(new BigDecimal(29.99)); + dprice.setProductAvailability(availability); + + ProductPriceDescription dpd = new ProductPriceDescription(); + dpd.setName("Base price"); + dpd.setProductPrice(dprice); + dpd.setLanguage(en); + + dprice.getDescriptions().add(dpd); + availability.getPrices().add(dprice); + + productPriceService.create(dprice); + + //get product + product = productService.getBySku("TESTSKU", store, en); + + + + + //check the product + Set avails = product.getAvailabilities(); + for(ProductAvailability as : avails) { + Set availabilityPrices = as.getPrices(); + for(ProductPrice ps : availabilityPrices) { + System.out.println(ps.getProductPriceAmount().toString()); + } + } + + //check availability + Set availabilityPrices = availability.getPrices(); + for(ProductPrice ps : availabilityPrices) { + System.out.println(ps.getProductPriceAmount().toString()); + } + + + + //configure shipping + ShippingConfiguration shippingConfiguration = new ShippingConfiguration(); + shippingConfiguration.setShippingBasisType(ShippingBasisType.SHIPPING);//based on shipping or billing address + shippingConfiguration.setShippingType(ShippingType.INTERNATIONAL); + shippingConfiguration.setShippingPackageType(ShippingPackageType.ITEM);//individual item pricing or box packaging (see unit test above) + //only if package type is package + shippingConfiguration.setBoxHeight(5); + shippingConfiguration.setBoxLength(5); + shippingConfiguration.setBoxWidth(5); + shippingConfiguration.setBoxWeight(1); + shippingConfiguration.setMaxWeight(10); + + List supportedCountries = new ArrayList(); + supportedCountries.add("CA"); + supportedCountries.add("US"); + supportedCountries.add("UK"); + supportedCountries.add("FR"); + + shippingService.setSupportedCountries(store, supportedCountries); + + + CustomShippingQuotesConfiguration customConfiguration = new CustomShippingQuotesConfiguration(); + customConfiguration.setModuleCode("weightBased"); + customConfiguration.setActive(true); + + CustomShippingQuotesRegion northRegion = new CustomShippingQuotesRegion(); + northRegion.setCustomRegionName("NORTH"); + + List countries = new ArrayList(); + countries.add("CA"); + countries.add("US"); + + northRegion.setCountries(countries); + + CustomShippingQuoteWeightItem caQuote4 = new CustomShippingQuoteWeightItem(); + caQuote4.setMaximumWeight(4); + caQuote4.setPrice(new BigDecimal(20)); + CustomShippingQuoteWeightItem caQuote10 = new CustomShippingQuoteWeightItem(); + caQuote10.setMaximumWeight(10); + caQuote10.setPrice(new BigDecimal(50)); + CustomShippingQuoteWeightItem caQuote100 = new CustomShippingQuoteWeightItem(); + caQuote100.setMaximumWeight(100); + caQuote100.setPrice(new BigDecimal(120)); + List quotes = new ArrayList(); + quotes.add(caQuote4); + quotes.add(caQuote10); + quotes.add(caQuote100); + + northRegion.setQuoteItems(quotes); + + customConfiguration.getRegions().add(northRegion); + + + //create an integration configuration - USPS + + IntegrationConfiguration configuration = new IntegrationConfiguration(); + configuration.setActive(true); + configuration.setEnvironment(Environment.TEST.name()); + configuration.setModuleCode("weightBased"); + + //configure module + + + + shippingService.saveShippingConfiguration(shippingConfiguration, store); + shippingService.saveShippingQuoteModuleConfiguration(configuration, store);//create the basic configuration + shippingService.saveCustomShippingConfiguration("weightBased", customConfiguration, store);//and the custom configuration + + //now create ShippingProduct + ShippingProduct shippingProduct1 = new ShippingProduct(product); + FinalPrice price = pricingService.calculateProductPrice(product); + shippingProduct1.setFinalPrice(price); + + List shippingProducts = new ArrayList(); + shippingProducts.add(shippingProduct1); + + Customer customer = new Customer(); + customer.setMerchantStore(store); + customer.setEmailAddress("test@test.com"); + customer.setGender(CustomerGender.M); + customer.setDefaultLanguage(en); + + customer.setAnonymous(true); + customer.setCompany("ifactory"); + customer.setDateOfBirth(new Date()); + customer.setNick("My nick"); + customer.setPassword("123456"); + + + Delivery delivery = new Delivery(); + delivery.setAddress("Shipping address"); + delivery.setCity("Boucherville"); + delivery.setCountry(country); + delivery.setZone(zone); + delivery.setPostalCode("J5C-6J4"); + + //overwrite delivery to US +/* delivery.setPostalCode("90002"); + delivery.setCountry(us); + Zone california = zoneService.getByCode("CA"); + delivery.setZone(california);*/ + + + Billing billing = new Billing(); + billing.setAddress("Billing address"); + billing.setCountry(country); + billing.setZone(zone); + billing.setPostalCode("J4B-8J9"); + billing.setFirstName("Carl"); + billing.setLastName("Samson"); + + customer.setBilling(billing); + customer.setDelivery(delivery); + + customerService.create(customer); + + Long dummyCartId = 0L;//for correlation + + ShippingQuote shippingQuote = shippingService.getShippingQuote(dummyCartId, store, delivery, shippingProducts, en); + + Assert.notNull(shippingQuote); + + } + + + +} \ No newline at end of file diff --git a/sm-core/src/test/java/com/salesmanager/test/shoppingcart/ShoppingCartTest.java b/sm-core/src/test/java/com/salesmanager/test/shoppingcart/ShoppingCartTest.java new file mode 100755 index 0000000000..531d2ac634 --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/shoppingcart/ShoppingCartTest.java @@ -0,0 +1,269 @@ +package com.salesmanager.test.shoppingcart; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +import org.junit.Assert; +import org.junit.Test; + +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.category.CategoryDescription; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionType; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValueDescription; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.description.ProductDescription; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.catalog.product.manufacturer.ManufacturerDescription; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPriceDescription; +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.core.model.shoppingcart.ShoppingCartAttributeItem; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; + + + +/** + * Test + * + * - Add a product to persistent shopping cart + * - Retrieve an item from the persistent shopping cart + * - Rebuild a shopping cart item after the product definition has been modified + * @author Carl Samson + * + */ +public class ShoppingCartTest extends com.salesmanager.test.common.AbstractSalesManagerCoreTestCase { + + + + @Test + public void createShoppingCart() throws Exception { + + MerchantStore store = merchantService.getByCode( MerchantStore.DEFAULT_STORE ); + + + Language en = languageService.getByCode("en"); + + + /** CATALOG CREATION **/ + + ProductType generalType = productTypeService.getProductType(ProductType.GENERAL_TYPE); + + /** + * Create the category + */ + Category shirts = new Category(); + shirts.setMerchantStore(store); + shirts.setCode("shirts"); + + CategoryDescription shirtsEnglishDescription = new CategoryDescription(); + shirtsEnglishDescription.setName("Shirts"); + shirtsEnglishDescription.setCategory(shirts); + shirtsEnglishDescription.setLanguage(en); + + Set descriptions = new HashSet(); + descriptions.add(shirtsEnglishDescription); + + + shirts.setDescriptions(descriptions); + categoryService.create(shirts); + + + /** + * Create a manufacturer + */ + Manufacturer addidas = new Manufacturer(); + addidas.setMerchantStore(store); + addidas.setCode("addidas"); + + ManufacturerDescription addidasDesc = new ManufacturerDescription(); + addidasDesc.setLanguage(en); + addidasDesc.setManufacturer(addidas); + addidasDesc.setName("Addidas"); + addidas.getDescriptions().add(addidasDesc); + + manufacturerService.create(addidas); + + /** + * Create an option + */ + ProductOption option = new ProductOption(); + option.setMerchantStore(store); + option.setCode("color"); + option.setProductOptionType(ProductOptionType.Radio.name()); + + ProductOptionDescription optionDescription = new ProductOptionDescription(); + optionDescription.setLanguage(en); + optionDescription.setName("Color"); + optionDescription.setDescription("Item color"); + optionDescription.setProductOption(option); + + option.getDescriptions().add(optionDescription); + + productOptionService.saveOrUpdate(option); + + + /** first option value **/ + ProductOptionValue white = new ProductOptionValue(); + white.setMerchantStore(store); + white.setCode("white"); + + ProductOptionValueDescription whiteDescription = new ProductOptionValueDescription(); + whiteDescription.setLanguage(en); + whiteDescription.setName("White"); + whiteDescription.setDescription("White color"); + whiteDescription.setProductOptionValue(white); + + white.getDescriptions().add(whiteDescription); + + productOptionValueService.saveOrUpdate(white); + + + ProductOptionValue black = new ProductOptionValue(); + black.setMerchantStore(store); + black.setCode("black"); + + /** second option value **/ + ProductOptionValueDescription blackDesc = new ProductOptionValueDescription(); + blackDesc.setLanguage(en); + blackDesc.setName("Black"); + blackDesc.setDescription("Black color"); + blackDesc.setProductOptionValue(black); + + black.getDescriptions().add(blackDesc); + + productOptionValueService.saveOrUpdate(black); + + + /** + * Create a complex product + */ + Product product = new Product(); + product.setProductHeight(new BigDecimal(4)); + product.setProductLength(new BigDecimal(3)); + product.setProductWidth(new BigDecimal(1)); + product.setSku("XABC12"); + product.setManufacturer(addidas); + product.setType(generalType); + product.setMerchantStore(store); + + // Product description + ProductDescription description = new ProductDescription(); + description.setName("Short sleeves shirt"); + description.setLanguage(en); + description.setProduct(product); + + product.getDescriptions().add(description); + product.getCategories().add(shirts); + + + //availability + ProductAvailability availability = new ProductAvailability(); + availability.setProductDateAvailable(new Date()); + availability.setProductQuantity(100); + availability.setRegion("*"); + availability.setProduct(product);// associate with product + + //price + ProductPrice dprice = new ProductPrice(); + dprice.setDefaultPrice(true); + dprice.setProductPriceAmount(new BigDecimal(29.99)); + dprice.setProductAvailability(availability); + + + + ProductPriceDescription dpd = new ProductPriceDescription(); + dpd.setName("Base price"); + dpd.setProductPrice(dprice); + dpd.setLanguage(en); + + dprice.getDescriptions().add(dpd); + availability.getPrices().add(dprice); + product.getAvailabilities().add(availability); + + + //attributes + //white + ProductAttribute whiteAttribute = new ProductAttribute(); + whiteAttribute.setProduct(product); + whiteAttribute.setProductOption(option); + whiteAttribute.setAttributeDefault(true); + whiteAttribute.setProductAttributePrice(new BigDecimal(0));//no price variation + whiteAttribute.setProductAttributeWeight(new BigDecimal(0));//no weight variation + whiteAttribute.setProductOption(option); + whiteAttribute.setProductOptionValue(white); + + product.getAttributes().add(whiteAttribute); + //black + ProductAttribute blackAttribute = new ProductAttribute(); + blackAttribute.setProduct(product); + blackAttribute.setProductOption(option); + blackAttribute.setProductAttributePrice(new BigDecimal(5));//5 + dollars + blackAttribute.setProductAttributeWeight(new BigDecimal(0));//no weight variation + blackAttribute.setProductOption(option); + blackAttribute.setProductOptionValue(black); + + product.getAttributes().add(blackAttribute); + + productService.saveProduct(product); + + /** Create Shopping cart **/ + + ShoppingCart shoppingCart = new ShoppingCart(); + shoppingCart.setMerchantStore(store); + + UUID cartCode = UUID.randomUUID(); + shoppingCart.setShoppingCartCode(cartCode.toString()); + + ShoppingCartItem item = new ShoppingCartItem(shoppingCart,product); + item.setSku(product.getSku()); + item.setShoppingCart(shoppingCart); + + FinalPrice price = pricingService.calculateProductPrice(product); + + item.setItemPrice(price.getFinalPrice()); + item.setQuantity(1); + + /** user selects black **/ + ShoppingCartAttributeItem attributeItem = new ShoppingCartAttributeItem(item,blackAttribute); + item.getAttributes().add(attributeItem); + + shoppingCart.getLineItems().add(item); + + + //create cart + shoppingCartService.create(shoppingCart); + + + /** Retrieve cart **/ + + ShoppingCart retrievedCart = shoppingCartService.getByCode(cartCode.toString(), store); + + Assert.assertNotNull(retrievedCart); + + /** Delete cart **/ + shoppingCartService.delete(retrievedCart); + + /** Check if cart has been deleted **/ + retrievedCart = shoppingCartService.getByCode(cartCode.toString(), store); + + Assert.assertNull(retrievedCart); + + // Clean up for other tests + categoryService.delete(shirts); + + } + + +} \ No newline at end of file diff --git a/sm-core/src/test/java/com/salesmanager/test/utils/ImportIntegrationModule.java b/sm-core/src/test/java/com/salesmanager/test/utils/ImportIntegrationModule.java new file mode 100755 index 0000000000..2c25d508b2 --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/utils/ImportIntegrationModule.java @@ -0,0 +1,124 @@ +package com.salesmanager.test.utils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.Map; + +import javax.inject.Inject; + +import org.junit.Ignore; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.reference.loader.IntegrationModulesLoader; +import com.salesmanager.core.business.services.system.ModuleConfigurationService; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.test.configuration.ConfigurationTest; + + + + + + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = {ConfigurationTest.class}) +@Ignore +public class ImportIntegrationModule { + + @Inject + private IntegrationModulesLoader integrationModulesLoader; + + + @Inject + private ModuleConfigurationService moduleCongigurationService; + + /** + * Import a specific integration module. Will delete and recreate the module + * if it already exists + * @throws Exception + */ + @Ignore + //@Test + public void importSpecificIntegrationModule() throws Exception { + + + ObjectMapper mapper = new ObjectMapper(); + File file = new File(" /Users/carlsamson/Documents/dev/workspaces/shopizer-master/shopizer/sm-core/src/main/resources/reference/integrationmodules.json"); + + + try (InputStream in = new FileInputStream(file)) { + + @SuppressWarnings("rawtypes") + Map[] objects = mapper.readValue(in, Map[].class); + + IntegrationModule module = null; + //get the module to be loaded + for (Map o : objects) { + //load that specific module + if (o.get("code").equals("beanstream")) { + //get module object + module = integrationModulesLoader.loadModule(o); + break; + } + } + + if (module != null) { + IntegrationModule m = moduleCongigurationService.getByCode(module.getCode()); + if (m != null) { + moduleCongigurationService.delete(m); + } + + moduleCongigurationService.create(module); + } + + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + /** + * Import all non existing modules + * @throws Exception + */ + @Ignore + //@Test + public void importNonExistingIntegrationModule() throws Exception { + + + ObjectMapper mapper = new ObjectMapper(); + File file = new File("/Users/carlsamson/Documents/dev/workspaces/shopizer-master/shopizer/sm-core/src/main/resources/reference/integrationmodules.json"); + + + try (InputStream in = new FileInputStream(file)) { + + @SuppressWarnings("rawtypes") + Map[] objects = mapper.readValue(in, Map[].class); + + + //get the module to be loaded + for (Map o : objects) { + //get module object + IntegrationModule module = integrationModulesLoader.loadModule(o); + + if (module != null) { + IntegrationModule m = moduleCongigurationService.getByCode(module.getCode()); + if (m == null) { + moduleCongigurationService.create(module); + } + } + + } + + + } catch (Exception e) { + throw new ServiceException(e); + } + + } + +} diff --git a/sm-core/src/test/java/com/salesmanager/test/utils/SendEmailTest.java b/sm-core/src/test/java/com/salesmanager/test/utils/SendEmailTest.java new file mode 100755 index 0000000000..ffc8c806a2 --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/utils/SendEmailTest.java @@ -0,0 +1,67 @@ +package com.salesmanager.test.utils; + +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Inject; + +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.email.Email; +import com.salesmanager.core.business.services.system.EmailService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.test.common.AbstractSalesManagerCoreTestCase; +import com.salesmanager.test.configuration.ConfigurationTest; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = {ConfigurationTest.class}) +@Ignore +public class SendEmailTest extends AbstractSalesManagerCoreTestCase { + + @Inject + private EmailService emailService; + + @Test + public void sendEmail() throws ServiceException, Exception { + + MerchantStore merchant = merchantService.getByCode( MerchantStore.DEFAULT_STORE ); + + Map templateTokens = new HashMap(); + templateTokens.put("EMAIL_ADMIN_LABEL", ""); + templateTokens.put("EMAIL_STORE_NAME", ""); + templateTokens.put("EMAIL_FOOTER_COPYRIGHT", ""); + templateTokens.put("EMAIL_DISCLAIMER", ""); + templateTokens.put("EMAIL_SPAM_DISCLAIMER", ""); + templateTokens.put("LOGOPATH", ""); + + + templateTokens.put("EMAIL_CONTACT_NAME", "Test"); + templateTokens.put("EMAIL_CONTACT_EMAIL", "test@gmail.com"); + templateTokens.put("EMAIL_CONTACT_CONTENT", "Hello"); + + templateTokens.put("EMAIL_CUSTOMER_CONTACT", "Contact"); + templateTokens.put("EMAIL_CONTACT_NAME_LABEL", "Name"); + templateTokens.put("EMAIL_CONTACT_EMAIL_LABEL", "Email"); + + + + Email email = new Email(); + email.setFrom("Default store"); + email.setFromEmail("test@shopizer.com"); + email.setSubject("Contact"); + email.setTo("test@shopizer.com"); + email.setTemplateName("email_template_contact.ftl"); + email.setTemplateTokens(templateTokens); + + emailService.sendHtmlEmail(merchant, email); + + + } + + +} diff --git a/sm-core/src/test/java/com/salesmanager/test/utils/UtilsTestCase.java b/sm-core/src/test/java/com/salesmanager/test/utils/UtilsTestCase.java new file mode 100755 index 0000000000..3e8eaebacf --- /dev/null +++ b/sm-core/src/test/java/com/salesmanager/test/utils/UtilsTestCase.java @@ -0,0 +1,96 @@ +package com.salesmanager.test.utils; + + + +import java.text.NumberFormat; +import java.util.List; +import java.util.Locale; + +import javax.inject.Inject; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.currency.CurrencyService; +import com.salesmanager.core.business.utils.CacheUtils; +import com.salesmanager.core.model.common.Address; +import com.salesmanager.core.model.reference.currency.Currency; +import com.salesmanager.core.modules.utils.Encryption; +import com.salesmanager.core.modules.utils.GeoLocation; +import com.salesmanager.test.configuration.ConfigurationTest; + + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = {ConfigurationTest.class}) +@Ignore +public class UtilsTestCase { + + + @Inject + private CountryService countryService; + + @Inject + private CurrencyService currencyService; + + @Inject + private Encryption encryption; + + @Inject + private CacheUtils cache; + + @Inject + private GeoLocation geoLoaction; + + + + //@Test + @Ignore + public void testCache() throws Exception { + + + + @SuppressWarnings("rawtypes") + List countries = countryService.list(); + + //CacheUtils cache = CacheUtils.getInstance(); + cache.putInCache(countries, "COUNTRIES"); + + @SuppressWarnings("rawtypes") + List objects = (List) cache.getFromCache("COUNTRIES"); + + Assert.assertNotNull(objects); + + } + + //@Test + @Ignore + public void testCurrency() throws Exception { + + Currency currency = currencyService.getByCode("BGN"); + + java.util.Currency c = currency.getCurrency(); + + NumberFormat numberFormat = NumberFormat.getCurrencyInstance(Locale.US); + numberFormat.setCurrency(c); + + System.out.println("Done"); + + } + + @Test + public void testGeoLocation() throws Exception { + + Address address = geoLoaction.getAddress("96.21.132.0"); + if(address!=null) { + System.out.println(address.getCountry()); + } + + } + + +} diff --git a/sm-core/src/test/resources/application.properties b/sm-core/src/test/resources/application.properties new file mode 100755 index 0000000000..82bb57c9a2 --- /dev/null +++ b/sm-core/src/test/resources/application.properties @@ -0,0 +1,18 @@ +spring.jpa.hibernate.use-new-id-generator-mappings=false +#Spring boot 2 +spring.main.allow-bean-definition-overriding= true + +logging.level.org.springframework.web=ERROR +logging.level.org.springframework.security=ERROR +logging.level.com.shopizer=INFO +logging.level.org.hibernate=ERROR +logging.level.org.apache.http.headers=ERROR +logging.level.org.apache.http.client=ERROR +logging.level.org.apache.http.impl=ERROR +logging.level.org.apache.http.wire=ERROR +logging.level.com.salesmanager=ERROR + +#default database schema +spring.jpa.properties.hibernate.default_schema=SALESMANAGER + +shopizer.test=true \ No newline at end of file diff --git a/sm-core/src/test/resources/database.properties b/sm-core/src/test/resources/database.properties new file mode 100755 index 0000000000..9bd6d42fac --- /dev/null +++ b/sm-core/src/test/resources/database.properties @@ -0,0 +1,25 @@ +## +## db configuration for test +## + +#for using memory database +db.jdbcUrl=jdbc\:h2\:mem\:SALESMANAGER-TEST;AUTOCOMMIT=OFF;mv_store=false;INIT\=RUNSCRIPT FROM 'src/test/resources/sql/create_schema.sql' +db.user=test +db.password=password +db.driverClass=org.h2.Driver +hibernate.dialect=org.hibernate.dialect.H2Dialect + +db.show.sql=false +db.schema=SALESMANAGER +hibernate.hbm2ddl.auto=create + +db.preferredTestQuery=SELECT 1 + + +## +## db pool settings +## +db.initialPoolSize=3 +db.minPoolSize=1 +db.maxPoolSize=3 + diff --git a/sm-core/src/test/resources/hbm2dll.properties b/sm-core/src/test/resources/hbm2dll.properties new file mode 100755 index 0000000000..13a3da4843 --- /dev/null +++ b/sm-core/src/test/resources/hbm2dll.properties @@ -0,0 +1 @@ +hibernate.dialect=org.hibernate.dialect.Oracle10gDialect \ No newline at end of file diff --git a/sm-core/src/test/resources/img/icon.png b/sm-core/src/test/resources/img/icon.png new file mode 100755 index 0000000000..12e7925ebf Binary files /dev/null and b/sm-core/src/test/resources/img/icon.png differ diff --git a/sm-core/src/test/resources/log4j.properties b/sm-core/src/test/resources/log4j.properties new file mode 100755 index 0000000000..3dabce3591 --- /dev/null +++ b/sm-core/src/test/resources/log4j.properties @@ -0,0 +1,17 @@ +log4j.appender.Stdout=org.apache.log4j.ConsoleAppender +log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.Stdout.layout.ConversionPattern=[%d{ISO8601}] %-5p - %-26.26c{1} - %m\n + +log4j.rootLogger=WARN,Stdout + +# hibernate queries +log4j.logger.org.hibernate=WARN +log4j.logger.org.hibernate.SQL=WARN +log4j.logger.org.hibernate.type=WARN +log4j.logger.org.apache.http.headers=WARN +log4j.logger.org.apache.http.wire=WARN + + +# schema initialization +log4j.logger.org.hibernate.tool.hbm2ddl=WARN +log4j.logger.org.springframework.transaction=WARN diff --git a/sm-core/src/test/resources/shopizer-core.properties b/sm-core/src/test/resources/shopizer-core.properties new file mode 100755 index 0000000000..0c1886e027 --- /dev/null +++ b/sm-core/src/test/resources/shopizer-core.properties @@ -0,0 +1,86 @@ + + +#Must be 16 digits (replace with your own creation !) +secretKey=7070200000000007 + + +#Elastic Search configurations +elasticsearch.cluster.name=shopizer +elasticsearch.mode=remote +elasticsearch.server.host=localhost +elasticsearch.server.protocole=http +elasticsearch.server.port=9200 +elasticsearch.server.proxy.user= +elasticsearch.server.proxy.password= +#enable if ES is secured (by default it is not) +elasticsearch.security.enabled=false +elasticsearch.security.user=elastic +elasticsearch.security.password=changeme + +#do not index in default profile +search.noindex=true + +# Which CMS method to use [ default | httpd | aws | gcp ] +# default = infinispan +# httpd = requires http server +# aws = AWS S3 -> See AWS S3 configuration below +# gcp = Google Cloud Storage + +config.cms.method=default + +config.cms.static.path=/static + + +#Infinispan configuration +#Specifies where files are located +config.cms.store.location=./files/store +config.cms.files.location=./files/repos + +#httpd configuration +#Specifies where htdocs repository is located +config.cms.http.path.location=/Applications/MAMP/htdocs/cms +config.cms.contentUrl=https://s3.ca-central-1.amazonaws.com/shopizer-lightsail + +#AWS S3 configuration +#Name of bucket files +#See regions here https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html +#Credentials must be set as environment variables when launching Shopizer +AWS_ACCESS_KEY_ID= +AWS_SECRETE_ACCESS_KEY= +config.cms.aws.bucket=shopizer-demo +config.cms.aws.region=ca-central-1 + +#GCP Cloud Storage configuration +#Name of the bucket file +#If the bucket does not exists it will be created +config.cms.gcp.bucket=shopizer-demo + +#Email implementation [default | ses] +#default=SpringHtmlEmailSender +#ses=AWS SES service +config.emailSender=default +config.emailSender.region=us_east_1 + +#Shipping activated in the system ? +config.displayShipping=true + + +#Google map API key +#For using priceByDistance shipping module +config.shippingDistancePreProcessor.apiKey= +config.shippingDistancePreProcessor.acceptedZones=QC,ON,AB,NY,MA + + +#Google map places +#checkout and signup address validation +#see : https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete-addressform +#Should be passed as an environment key +config.googleMapsKey= + +#recaptcha https://developers.google.com/recaptcha/ +config.recaptcha.secretKey= +config.recaptcha.siteKey= + +#shipping rules +config.shipping.rule.priceByDistance=PriceByDistance.drl +config.shipping.rule.shippingModuleDecision=ShippingDecision.drl diff --git a/sm-core/src/test/resources/shopizer-properties.properties b/sm-core/src/test/resources/shopizer-properties.properties new file mode 100755 index 0000000000..f496d57b64 --- /dev/null +++ b/sm-core/src/test/resources/shopizer-properties.properties @@ -0,0 +1,17 @@ +MULTIPLE_PRICE_AVAILABILITY=false +INDEX_PRODUCTS=true +PRODUCT_IMAGE_WIDTH_SIZE=1000 +PRODUCT_IMAGE_HEIGHT_SIZE=800 +CROP_UPLOADED_IMAGES=false +PRODUCT_IMAGE_MAX_HEIGHT_SIZE=2000 +PRODUCT_IMAGE_MAX_WIDTH_SIZE=4000 +PRODUCT_IMAGE_MAX_SIZE=9000000 +IMAGE_FORMATS=jpg|png|gif +POPULATE_TEST_DATA=false +SHOP_SCHEME=http +CONTEXT_PATH= +URL_EXTENSION=.html +SEARCH_QUERY= +AUTOCOMPLETE_QUERY= +#deprecated +shopizer.googlemaps_key=NO \ No newline at end of file diff --git a/sm-core/src/test/resources/spring/test-shopizer-context.xml b/sm-core/src/test/resources/spring/test-shopizer-context.xml new file mode 100755 index 0000000000..f73a40abcf --- /dev/null +++ b/sm-core/src/test/resources/spring/test-shopizer-context.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + false + false + + http + sm-shop + + 350 + 375 + false + + + 2000 + 4000 + 9000000 + jpg|png|gif + + true + + + + diff --git a/sm-core/src/test/resources/sql/create_schema.sql b/sm-core/src/test/resources/sql/create_schema.sql new file mode 100755 index 0000000000..a450d11676 --- /dev/null +++ b/sm-core/src/test/resources/sql/create_schema.sql @@ -0,0 +1 @@ +create schema IF NOT EXISTS SALESMANAGER; \ No newline at end of file diff --git a/sm-core/src/test/resources/vault.properties b/sm-core/src/test/resources/vault.properties new file mode 100755 index 0000000000..8b13789179 --- /dev/null +++ b/sm-core/src/test/resources/vault.properties @@ -0,0 +1 @@ + diff --git a/sm-shop-model/.mvn/wrapper/MavenWrapperDownloader.java b/sm-shop-model/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100755 index 0000000000..fa4f7b499f --- /dev/null +++ b/sm-shop-model/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,110 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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 + + http://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. +*/ + +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = + "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: : " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/sm-shop-model/.mvn/wrapper/maven-wrapper.properties b/sm-shop-model/.mvn/wrapper/maven-wrapper.properties new file mode 100755 index 0000000000..a5fcc11920 --- /dev/null +++ b/sm-shop-model/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip \ No newline at end of file diff --git a/sm-shop-model/mvnw b/sm-shop-model/mvnw new file mode 100755 index 0000000000..5551fde8e7 --- /dev/null +++ b/sm-shop-model/mvnw @@ -0,0 +1,286 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + wget "$jarUrl" -O "$wrapperJarPath" + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + curl -o "$wrapperJarPath" "$jarUrl" + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/sm-shop-model/mvnw.cmd b/sm-shop-model/mvnw.cmd new file mode 100755 index 0000000000..48363fa60b --- /dev/null +++ b/sm-shop-model/mvnw.cmd @@ -0,0 +1,161 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" +FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + echo Found %WRAPPER_JAR% +) else ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" + echo Finished downloading %WRAPPER_JAR% +) +@REM End of extension + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/sm-shop-model/pom.xml b/sm-shop-model/pom.xml new file mode 100755 index 0000000000..c5e48265c3 --- /dev/null +++ b/sm-shop-model/pom.xml @@ -0,0 +1,161 @@ + + 4.0.0 + + com.shopizer + shopizer + 3.2.5 + + + sm-shop-model + sm-shop-model + sm-shop-model contains Shopizer model objects for api + http://www.shopizer.com + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + scm:git:git://github.com:shopizer-ecommerce/shopizer-sm-shop-model.git + scm:git:ssh://github.com:shopizer-ecommerce/shopizer-sm-shop-model.git + + https://github.com/shopizer-ecommerce/shopizer-sm-shop-model + + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + + + + + + Shopizer Team + team@shopizer.com + Shopizer + http://www.shopizer.com + + + + + + + + com.shopizer + sm-core-model + + + + org.springframework + spring-core + + + + org.springframework + spring-webmvc + + + + javax.annotation + javax.annotation-api + + + + + io.springfox + springfox-swagger2 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/NamedEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/NamedEntity.java new file mode 100755 index 0000000000..ae22ef5ee3 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/NamedEntity.java @@ -0,0 +1,67 @@ +package com.salesmanager.shop.model.catalog; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.ShopEntity; + + +public abstract class NamedEntity extends ShopEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String name; + private String description; + private String friendlyUrl; + private String keyWords; + private String highlights; + private String metaDescription; + private String title; + + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + public String getFriendlyUrl() { + return friendlyUrl; + } + public void setFriendlyUrl(String friendlyUrl) { + this.friendlyUrl = friendlyUrl; + } + public String getKeyWords() { + return keyWords; + } + public void setKeyWords(String keyWords) { + this.keyWords = keyWords; + } + public String getHighlights() { + return highlights; + } + public void setHighlights(String highlights) { + this.highlights = highlights; + } + public String getMetaDescription() { + return metaDescription; + } + public void setMetaDescription(String metaDescription) { + this.metaDescription = metaDescription; + } + public String getTitle() { + return title; + } + public void setTitle(String title) { + this.title = title; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/ProductList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/ProductList.java new file mode 100755 index 0000000000..a45976251b --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/ProductList.java @@ -0,0 +1,47 @@ +package com.salesmanager.shop.model.catalog; + +import com.salesmanager.shop.model.catalog.product.ReadableProduct; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +public class ProductList implements Serializable { + + + /** + * + */ + private static final long serialVersionUID = 1L; + private int productCount; + private BigDecimal minPrice; + private BigDecimal maxPrice; + private List products = new ArrayList(); + public void setProducts(List products) { + this.products = products; + } + public List getProducts() { + return products; + } + public int getProductCount() { + return productCount; + } + public void setProductCount(int productCount) { + this.productCount = productCount; + } + public BigDecimal getMinPrice() { + return minPrice; + } + public void setMinPrice(BigDecimal minPrice) { + this.minPrice = minPrice; + } + public BigDecimal getMaxPrice() { + return maxPrice; + } + public void setMaxPrice(BigDecimal maxPrice) { + this.maxPrice = maxPrice; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/SearchProductList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/SearchProductList.java new file mode 100755 index 0000000000..3415171095 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/SearchProductList.java @@ -0,0 +1,27 @@ +package com.salesmanager.shop.model.catalog; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.category.ReadableCategory; + + +/** + * Object representing the results of a search query + * @author Carl Samson + * + */ +public class SearchProductList extends ProductList { + + + private static final long serialVersionUID = 1L; + private List categoryFacets = new ArrayList(); + public List getCategoryFacets() { + return categoryFacets; + } + public void setCategoryFacets(List categoryFacets) { + this.categoryFacets = categoryFacets; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/SearchProductRequest.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/SearchProductRequest.java new file mode 100755 index 0000000000..177eeaad9d --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/SearchProductRequest.java @@ -0,0 +1,49 @@ +package com.salesmanager.shop.model.catalog; + +import java.io.Serializable; + +import javax.validation.constraints.NotEmpty; + +/** + * Search product request + * @author c.samson + * + */ +public class SearchProductRequest implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private static final int DEFAULT_COUNT = 100; + private static final int START_COUNT = 0; + @NotEmpty + private String query; + private int count = DEFAULT_COUNT; + private int start = START_COUNT; + + public String getQuery() { + return query; + } + + public void setQuery(String query) { + this.query = query; + } + + public int getStart() { + return start; + } + + public void setStart(int start) { + this.start = start; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/CatalogEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/CatalogEntity.java new file mode 100644 index 0000000000..7058f815de --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/CatalogEntity.java @@ -0,0 +1,36 @@ +package com.salesmanager.shop.model.catalog.catalog; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + +public class CatalogEntity extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private boolean visible; + private boolean defaultCatalog; + private String code; + public boolean isVisible() { + return visible; + } + public void setVisible(boolean visible) { + this.visible = visible; + } + public boolean isDefaultCatalog() { + return defaultCatalog; + } + public void setDefaultCatalog(boolean defaultCatalog) { + this.defaultCatalog = defaultCatalog; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/CatalogEntryEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/CatalogEntryEntity.java new file mode 100644 index 0000000000..6a17f83b80 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/CatalogEntryEntity.java @@ -0,0 +1,26 @@ +package com.salesmanager.shop.model.catalog.catalog; + +import com.salesmanager.shop.model.entity.Entity; + +public class CatalogEntryEntity extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String catalog; + private boolean visible; + public String getCatalog() { + return catalog; + } + public void setCatalog(String catalog) { + this.catalog = catalog; + } + public boolean isVisible() { + return visible; + } + public void setVisible(boolean visible) { + this.visible = visible; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/PersistableCatalog.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/PersistableCatalog.java new file mode 100644 index 0000000000..0f976e6e5f --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/PersistableCatalog.java @@ -0,0 +1,10 @@ +package com.salesmanager.shop.model.catalog.catalog; + +public class PersistableCatalog extends CatalogEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/PersistableCatalogCategoryEntry.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/PersistableCatalogCategoryEntry.java new file mode 100644 index 0000000000..13385b1acf --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/PersistableCatalogCategoryEntry.java @@ -0,0 +1,24 @@ +package com.salesmanager.shop.model.catalog.catalog; + +public class PersistableCatalogCategoryEntry extends CatalogEntryEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String productCode; + private String categoryCode; + public String getProductCode() { + return productCode; + } + public void setProductCode(String productCode) { + this.productCode = productCode; + } + public String getCategoryCode() { + return categoryCode; + } + public void setCategoryCode(String categoryCode) { + this.categoryCode = categoryCode; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/ReadableCatalog.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/ReadableCatalog.java new file mode 100644 index 0000000000..7835ae01ef --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/ReadableCatalog.java @@ -0,0 +1,43 @@ +package com.salesmanager.shop.model.catalog.catalog; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.category.ReadableCategory; +import com.salesmanager.shop.model.store.ReadableMerchantStore; + +public class ReadableCatalog extends ReadableCatalogName { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private ReadableMerchantStore store; + + private List category = new ArrayList(); + + +/* public List getEntry() { + return entry; + } + public void setEntry(List entry) { + this.entry = entry; + }*/ + + public ReadableMerchantStore getStore() { + return store; + } + public void setStore(ReadableMerchantStore store) { + this.store = store; + } + public List getCategory() { + return category; + } + public void setCategory(List category) { + this.category = category; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/ReadableCatalogCategoryEntry.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/ReadableCatalogCategoryEntry.java new file mode 100644 index 0000000000..9d10452d8e --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/ReadableCatalogCategoryEntry.java @@ -0,0 +1,33 @@ +package com.salesmanager.shop.model.catalog.catalog; + +import com.salesmanager.shop.model.catalog.category.ReadableCategory; + +public class ReadableCatalogCategoryEntry extends CatalogEntryEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String creationDate; + //private ReadableProduct product; + private ReadableCategory category; + public String getCreationDate() { + return creationDate; + } + public void setCreationDate(String creationDate) { + this.creationDate = creationDate; + } +/* public ReadableProduct getProduct() { + return product; + } + public void setProduct(ReadableProduct product) { + this.product = product; + }*/ + public ReadableCategory getCategory() { + return category; + } + public void setCategory(ReadableCategory category) { + this.category = category; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/ReadableCatalogList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/ReadableCatalogList.java new file mode 100644 index 0000000000..454339dabd --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/ReadableCatalogList.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.catalog.catalog; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.entity.ReadableList; + +public class ReadableCatalogList extends ReadableList { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List catalogs = new ArrayList(); + public List getCatalogs() { + return catalogs; + } + public void setCatalogs(List catalogs) { + this.catalogs = catalogs; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/ReadableCatalogName.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/ReadableCatalogName.java new file mode 100644 index 0000000000..05aca2388f --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/catalog/ReadableCatalogName.java @@ -0,0 +1,20 @@ +package com.salesmanager.shop.model.catalog.catalog; + +public class ReadableCatalogName extends CatalogEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String creationDate; + + public String getCreationDate() { + return creationDate; + } + + public void setCreationDate(String creationDate) { + this.creationDate = creationDate; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/Category.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/Category.java new file mode 100755 index 0000000000..3544777f86 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/Category.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.catalog.category; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + + +public class Category extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String code; + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/CategoryDescription.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/CategoryDescription.java new file mode 100755 index 0000000000..713cb0e3e8 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/CategoryDescription.java @@ -0,0 +1,16 @@ +package com.salesmanager.shop.model.catalog.category; + +import java.io.Serializable; + +import com.salesmanager.shop.model.catalog.NamedEntity; + + + +public class CategoryDescription extends NamedEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/CategoryEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/CategoryEntity.java new file mode 100755 index 0000000000..d221ccdbc5 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/CategoryEntity.java @@ -0,0 +1,60 @@ +package com.salesmanager.shop.model.catalog.category; + +import java.io.Serializable; + +public class CategoryEntity extends Category implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + + + + private int sortOrder; + private boolean visible; + private boolean featured; + private String lineage; + private int depth; + private Category parent; + + + public int getSortOrder() { + return sortOrder; + } + public void setSortOrder(int sortOrder) { + this.sortOrder = sortOrder; + } + public boolean isVisible() { + return visible; + } + public void setVisible(boolean visible) { + this.visible = visible; + } + public String getLineage() { + return lineage; + } + public void setLineage(String lineage) { + this.lineage = lineage; + } + public int getDepth() { + return depth; + } + public void setDepth(int depth) { + this.depth = depth; + } + public Category getParent() { + return parent; + } + public void setParent(Category parent) { + this.parent = parent; + } + public boolean isFeatured() { + return featured; + } + public void setFeatured(boolean featured) { + this.featured = featured; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/PersistableCategory.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/PersistableCategory.java new file mode 100755 index 0000000000..256961c190 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/PersistableCategory.java @@ -0,0 +1,29 @@ +package com.salesmanager.shop.model.catalog.category; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class PersistableCategory extends CategoryEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List descriptions;//always persist description + private List children = new ArrayList(); + + public List getDescriptions() { + return descriptions; + } + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + public List getChildren() { + return children; + } + public void setChildren(List children) { + this.children = children; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/ReadableCategory.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/ReadableCategory.java new file mode 100755 index 0000000000..6cbdf2d48e --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/ReadableCategory.java @@ -0,0 +1,44 @@ +package com.salesmanager.shop.model.catalog.category; + +import java.util.ArrayList; +import java.util.List; + +public class ReadableCategory extends CategoryEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private CategoryDescription description;//one category based on language + private int productCount; + private String store; + private List children = new ArrayList(); + + + public void setDescription(CategoryDescription description) { + this.description = description; + } + public CategoryDescription getDescription() { + return description; + } + + public int getProductCount() { + return productCount; + } + public void setProductCount(int productCount) { + this.productCount = productCount; + } + public List getChildren() { + return children; + } + public void setChildren(List children) { + this.children = children; + } + public String getStore() { + return store; + } + public void setStore(String store) { + this.store = store; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/ReadableCategoryFull.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/ReadableCategoryFull.java new file mode 100755 index 0000000000..60e958f2cb --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/ReadableCategoryFull.java @@ -0,0 +1,23 @@ +package com.salesmanager.shop.model.catalog.category; + +import java.util.ArrayList; +import java.util.List; + +public class ReadableCategoryFull extends ReadableCategory { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private List descriptions = new ArrayList(); + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/ReadableCategoryList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/ReadableCategoryList.java new file mode 100644 index 0000000000..ae164e985e --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/ReadableCategoryList.java @@ -0,0 +1,21 @@ +package com.salesmanager.shop.model.catalog.category; + +import java.util.ArrayList; +import java.util.List; +import com.salesmanager.shop.model.entity.ReadableList; + +public class ReadableCategoryList extends ReadableList { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List categories = new ArrayList(); + public List getCategories() { + return categories; + } + public void setCategories(List categories) { + this.categories = categories; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/ReadableCategoryName.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/ReadableCategoryName.java new file mode 100644 index 0000000000..fc26371a64 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/category/ReadableCategoryName.java @@ -0,0 +1,17 @@ +package com.salesmanager.shop.model.catalog.category; + +public class ReadableCategoryName extends CategoryEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String name; + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/Manufacturer.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/Manufacturer.java new file mode 100755 index 0000000000..ed6d21a56a --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/Manufacturer.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.catalog.manufacturer; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + + +public class Manufacturer extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String code; + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/ManufacturerDescription.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/ManufacturerDescription.java new file mode 100755 index 0000000000..7da09ecc30 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/ManufacturerDescription.java @@ -0,0 +1,16 @@ +package com.salesmanager.shop.model.catalog.manufacturer; + +import java.io.Serializable; + +import com.salesmanager.shop.model.catalog.NamedEntity; + + +public class ManufacturerDescription extends NamedEntity implements + Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/ManufacturerEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/ManufacturerEntity.java new file mode 100755 index 0000000000..401f5ebec9 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/ManufacturerEntity.java @@ -0,0 +1,23 @@ +package com.salesmanager.shop.model.catalog.manufacturer; + +import java.io.Serializable; + + + +public class ManufacturerEntity extends Manufacturer implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private int order; + + public void setOrder(int order) { + this.order = order; + } + public int getOrder() { + return order; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/PersistableManufacturer.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/PersistableManufacturer.java new file mode 100755 index 0000000000..88099fc471 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/PersistableManufacturer.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.catalog.manufacturer; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class PersistableManufacturer extends ManufacturerEntity implements + Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List descriptions = new ArrayList(); + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + public List getDescriptions() { + return descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/ReadableManufacturer.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/ReadableManufacturer.java new file mode 100755 index 0000000000..d9cabd9777 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/ReadableManufacturer.java @@ -0,0 +1,20 @@ +package com.salesmanager.shop.model.catalog.manufacturer; + +import java.io.Serializable; + +public class ReadableManufacturer extends ManufacturerEntity implements + Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private ManufacturerDescription description; + public void setDescription(ManufacturerDescription description) { + this.description = description; + } + public ManufacturerDescription getDescription() { + return description; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/ReadableManufacturerFull.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/ReadableManufacturerFull.java new file mode 100644 index 0000000000..b617590025 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/ReadableManufacturerFull.java @@ -0,0 +1,21 @@ +package com.salesmanager.shop.model.catalog.manufacturer; + +import java.util.List; + +public class ReadableManufacturerFull extends ReadableManufacturer { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List descriptions; + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/ReadableManufacturerList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/ReadableManufacturerList.java new file mode 100644 index 0000000000..6fce43373f --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/manufacturer/ReadableManufacturerList.java @@ -0,0 +1,24 @@ +package com.salesmanager.shop.model.catalog.manufacturer; + +import java.util.ArrayList; +import java.util.List; +import com.salesmanager.shop.model.entity.ReadableList; + +public class ReadableManufacturerList extends ReadableList { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private List manufacturers = new ArrayList(); + + public List getManufacturers() { + return manufacturers; + } + + public void setManufacturers(List manufacturers) { + this.manufacturers = manufacturers; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/LightPersistableProduct.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/LightPersistableProduct.java new file mode 100755 index 0000000000..d86f7e8472 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/LightPersistableProduct.java @@ -0,0 +1,42 @@ +package com.salesmanager.shop.model.catalog.product; + +import java.io.Serializable; + +/** + * Lightweight version of Persistable product + * @author carlsamson + * + */ +public class LightPersistableProduct implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String price; + private boolean available; + private boolean productShipeable; + private int quantity; + public String getPrice() { + return price; + } + public void setPrice(String price) { + this.price = price; + } + + public int getQuantity() { + return quantity; + } + public void setQuantity(int quantity) { + this.quantity = quantity; + } + public boolean isAvailable() { + return available; + } + public void setAvailable(boolean available) { + this.available = available; + } + public boolean isProductShipeable() { return productShipeable; } + public void setProductShipeable(Boolean productShipeable) { this.productShipeable = productShipeable; } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/PersistableImage.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/PersistableImage.java new file mode 100755 index 0000000000..c484bdf1fb --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/PersistableImage.java @@ -0,0 +1,106 @@ +package com.salesmanager.shop.model.catalog.product; + +import org.springframework.web.multipart.MultipartFile; +import com.salesmanager.shop.model.entity.Entity; + +public class PersistableImage extends Entity { + + + private static final long serialVersionUID = 1L; + private boolean defaultImage; + private int imageType = 0; + private String name = null; + private String path = null; + + private MultipartFile[] files; + private byte[] bytes = null; + private String contentType = null; + + + /** + * An external image url + */ + private String imageUrl = null; + + + + public void setBytes(byte[] bytes) { + this.bytes = bytes; + } + + + public byte[] getBytes() { + return bytes; + } + + + public void setContentType(String contentType) { + this.contentType = contentType; + } + + + public String getContentType() { + return contentType; + } + + + public String getImageUrl() { + return imageUrl; + } + + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + + + public int getImageType() { + return imageType; + } + + + public void setImageType(int imageType) { + this.imageType = imageType; + } + + + public boolean isDefaultImage() { + return defaultImage; + } + + + public void setDefaultImage(boolean defaultImage) { + this.defaultImage = defaultImage; + } + + + public String getName() { + return name; + } + + + public void setName(String name) { + this.name = name; + } + + + public String getPath() { + return path; + } + + + public void setPath(String path) { + this.path = path; + } + + + public MultipartFile[] getFiles() { + return files; + } + + + public void setFiles(MultipartFile[] files) { + this.files = files; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/PersistableProductPrice.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/PersistableProductPrice.java new file mode 100755 index 0000000000..bfe1eab004 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/PersistableProductPrice.java @@ -0,0 +1,42 @@ +package com.salesmanager.shop.model.catalog.product; + +import java.util.ArrayList; +import java.util.List; + +public class PersistableProductPrice extends ProductPriceEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String sku; + private Long productAvailabilityId; + + private List descriptions = new ArrayList(); + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + + public Long getProductAvailabilityId() { + return productAvailabilityId; + } + + public void setProductAvailabilityId(Long productAvailabilityId) { + this.productAvailabilityId = productAvailabilityId; + } + + public String getSku() { + return sku; + } + + public void setSku(String sku) { + this.sku = sku; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/PersistableProductReview.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/PersistableProductReview.java new file mode 100755 index 0000000000..911802a9bc --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/PersistableProductReview.java @@ -0,0 +1,25 @@ +package com.salesmanager.shop.model.catalog.product; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +public class PersistableProductReview extends ProductReviewEntity implements + Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + @NotNull + private Long customerId; + public Long getCustomerId() { + return customerId; + } + public void setCustomerId(Long customerId) { + this.customerId = customerId; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/Product.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/Product.java new file mode 100755 index 0000000000..5107aac8c3 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/Product.java @@ -0,0 +1,63 @@ +package com.salesmanager.shop.model.catalog.product; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + + +public class Product extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private boolean productShipeable = false; + + private boolean available; + private boolean visible = true; + + private int sortOrder; + private String dateAvailable; + private String creationDate; + + public boolean isProductShipeable() { + return productShipeable; + } + public void setProductShipeable(boolean productShipeable) { + this.productShipeable = productShipeable; + } + public boolean isAvailable() { + return available; + } + public void setAvailable(boolean available) { + this.available = available; + } + public int getSortOrder() { + return sortOrder; + } + public void setSortOrder(int sortOrder) { + this.sortOrder = sortOrder; + } + public String getDateAvailable() { + return dateAvailable; + } + public void setDateAvailable(String dateAvailable) { + this.dateAvailable = dateAvailable; + } + public String getCreationDate() { + return creationDate; + } + public void setCreationDate(String creationDate) { + this.creationDate = creationDate; + } + public boolean isVisible() { + return visible; + } + public void setVisible(boolean visible) { + this.visible = visible; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductDescription.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductDescription.java new file mode 100755 index 0000000000..d4a4d2cdb7 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductDescription.java @@ -0,0 +1,12 @@ +package com.salesmanager.shop.model.catalog.product; + +import com.salesmanager.shop.model.catalog.NamedEntity; + +public class ProductDescription extends NamedEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductPrice.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductPrice.java new file mode 100755 index 0000000000..c139047d98 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductPrice.java @@ -0,0 +1,14 @@ +package com.salesmanager.shop.model.catalog.product; + +import com.salesmanager.shop.model.entity.Entity; + +public class ProductPrice extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public final static String DEFAULT_PRICE_CODE="base"; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductPriceDescription.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductPriceDescription.java new file mode 100644 index 0000000000..58c7c3af9f --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductPriceDescription.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.catalog.product; + +import com.salesmanager.shop.model.catalog.NamedEntity; + +public class ProductPriceDescription extends NamedEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String priceAppender; + + public String getPriceAppender() { + return priceAppender; + } + + public void setPriceAppender(String priceAppender) { + this.priceAppender = priceAppender; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductPriceEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductPriceEntity.java new file mode 100755 index 0000000000..81842dfc03 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductPriceEntity.java @@ -0,0 +1,79 @@ +package com.salesmanager.shop.model.catalog.product; + +import java.io.Serializable; +import java.math.BigDecimal; + +import org.apache.commons.lang3.StringUtils; +/** + * A product entity is used by services API + * to populate or retrieve a Product price entity + * @author Carl Samson + * + */ +public class ProductPriceEntity extends ProductPrice implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String code; + private boolean discounted = false; + private String discountStartDate; + private String discountEndDate; + private boolean defaultPrice = true; + private BigDecimal price; + private BigDecimal discountedPrice; + + public boolean isDiscounted() { + return discounted; + } + public void setDiscounted(boolean discounted) { + this.discounted = discounted; + } + public String getDiscountStartDate() { + return discountStartDate; + } + public void setDiscountStartDate(String discountStartDate) { + this.discountStartDate = discountStartDate; + } + public String getDiscountEndDate() { + return discountEndDate; + } + public void setDiscountEndDate(String discountEndDate) { + this.discountEndDate = discountEndDate; + } + public boolean isDefaultPrice() { + return defaultPrice; + } + public void setDefaultPrice(boolean defaultPrice) { + this.defaultPrice = defaultPrice; + } + + public BigDecimal getDiscountedPrice() { + return discountedPrice; + } + public void setDiscountedPrice(BigDecimal discountedPrice) { + this.discountedPrice = discountedPrice; + } + public String getCode() { + if(StringUtils.isBlank(this.code)) { + code = DEFAULT_PRICE_CODE; + } + return code; + } + public void setCode(String code) { + this.code = code; + } + public BigDecimal getPrice() { + return price; + } + public void setPrice(BigDecimal price) { + this.price = price; + } + + + + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductPriceRequest.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductPriceRequest.java new file mode 100644 index 0000000000..c6fa5df546 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductPriceRequest.java @@ -0,0 +1,34 @@ +package com.salesmanager.shop.model.catalog.product; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.attribute.ProductAttribute; + +public class ProductPriceRequest implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List options = new ArrayList(); + private String sku;//product instance sku + + public List getOptions() { + return options; + } + + public void setOptions(List options) { + this.options = options; + } + + public String getSku() { + return sku; + } + + public void setSku(String sku) { + this.sku = sku; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductReviewEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductReviewEntity.java new file mode 100755 index 0000000000..f2c82631bd --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ProductReviewEntity.java @@ -0,0 +1,56 @@ +package com.salesmanager.shop.model.catalog.product; + +import java.io.Serializable; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +import javax.validation.constraints.NotEmpty; + +import com.salesmanager.shop.model.entity.ShopEntity; + + +public class ProductReviewEntity extends ShopEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + @NotEmpty + private String description; + private Long productId; + private String date; + + @NotNull + @Min(1) + @Max(5) + private Double rating; + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + public Long getProductId() { + return productId; + } + public void setProductId(Long productId) { + this.productId = productId; + } + + public Double getRating() { + return rating; + } + public void setRating(Double rating) { + this.rating = rating; + } + public String getDate() { + return date; + } + public void setDate(String date) { + this.date = date; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableImage.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableImage.java new file mode 100755 index 0000000000..84d62ef8e2 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableImage.java @@ -0,0 +1,63 @@ +package com.salesmanager.shop.model.catalog.product; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + +public class ReadableImage extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String imageName; + private String imageUrl; + private String externalUrl; + private String videoUrl; + private int imageType; + private int order; + private boolean defaultImage; + public void setImageName(String imageName) { + this.imageName = imageName; + } + public String getImageName() { + return imageName; + } + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + public String getImageUrl() { + return imageUrl; + } + public int getImageType() { + return imageType; + } + public void setImageType(int imageType) { + this.imageType = imageType; + } + public String getExternalUrl() { + return externalUrl; + } + public void setExternalUrl(String externalUrl) { + this.externalUrl = externalUrl; + } + public String getVideoUrl() { + return videoUrl; + } + public void setVideoUrl(String videoUrl) { + this.videoUrl = videoUrl; + } + public boolean isDefaultImage() { + return defaultImage; + } + public void setDefaultImage(boolean defaultImage) { + this.defaultImage = defaultImage; + } + public int getOrder() { + return order; + } + public void setOrder(int order) { + this.order = order; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableMinimalProduct.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableMinimalProduct.java new file mode 100644 index 0000000000..5647cbee49 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableMinimalProduct.java @@ -0,0 +1,62 @@ +package com.salesmanager.shop.model.catalog.product; + +import java.io.Serializable; +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.product.ProductEntity; +import com.salesmanager.shop.model.entity.ReadableDescription; + +public class ReadableMinimalProduct extends ProductEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private ReadableDescription description; + private ReadableProductPrice productPrice; + private String finalPrice = "0"; + private String originalPrice = null; + private ReadableImage image; + private List images; + + + public ReadableDescription getDescription() { + return description; + } + public void setDescription(ReadableDescription description) { + this.description = description; + } + public ReadableProductPrice getProductPrice() { + return productPrice; + } + public void setProductPrice(ReadableProductPrice productPrice) { + this.productPrice = productPrice; + } + public String getFinalPrice() { + return finalPrice; + } + public void setFinalPrice(String finalPrice) { + this.finalPrice = finalPrice; + } + public String getOriginalPrice() { + return originalPrice; + } + public void setOriginalPrice(String originalPrice) { + this.originalPrice = originalPrice; + } + public ReadableImage getImage() { + return image; + } + public void setImage(ReadableImage image) { + this.image = image; + } + public List getImages() { + return images; + } + public void setImages(List images) { + this.images = images; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProduct.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProduct.java new file mode 100755 index 0000000000..7fdb7bd03d --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProduct.java @@ -0,0 +1,172 @@ +package com.salesmanager.shop.model.catalog.product; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.category.ReadableCategory; +import com.salesmanager.shop.model.catalog.manufacturer.ReadableManufacturer; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductAttribute; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductOption; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductProperty; +import com.salesmanager.shop.model.catalog.product.product.ProductEntity; +import com.salesmanager.shop.model.catalog.product.product.variant.ReadableProductVariant; +import com.salesmanager.shop.model.catalog.product.type.ReadableProductType; + +public class ReadableProduct extends ProductEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private ProductDescription description; + private ReadableProductPrice productPrice; + private String finalPrice = "0"; + private String originalPrice = null; + private boolean discounted = false; + private ReadableImage image; + private List images = new ArrayList(); + private ReadableManufacturer manufacturer; + private List attributes = new ArrayList(); + private List options = new ArrayList(); + private List variants = new ArrayList(); + private List properties = new ArrayList(); + private List categories = new ArrayList(); + private ReadableProductType type; + private boolean canBePurchased = false; + + // RENTAL + private RentalOwner owner; + + public ProductDescription getDescription() { + return description; + } + + public void setDescription(ProductDescription description) { + this.description = description; + } + + public String getFinalPrice() { + return finalPrice; + } + + public void setFinalPrice(String finalPrice) { + this.finalPrice = finalPrice; + } + + public String getOriginalPrice() { + return originalPrice; + } + + public void setOriginalPrice(String originalPrice) { + this.originalPrice = originalPrice; + } + + public boolean isDiscounted() { + return discounted; + } + + public void setDiscounted(boolean discounted) { + this.discounted = discounted; + } + + public void setImages(List images) { + this.images = images; + } + + public List getImages() { + return images; + } + + public void setImage(ReadableImage image) { + this.image = image; + } + + public ReadableImage getImage() { + return image; + } + + public void setAttributes(List attributes) { + this.attributes = attributes; + } + + public List getAttributes() { + return attributes; + } + + public void setManufacturer(ReadableManufacturer manufacturer) { + this.manufacturer = manufacturer; + } + + public ReadableManufacturer getManufacturer() { + return manufacturer; + } + + public boolean isCanBePurchased() { + return canBePurchased; + } + + public void setCanBePurchased(boolean canBePurchased) { + this.canBePurchased = canBePurchased; + } + + public RentalOwner getOwner() { + return owner; + } + + public void setOwner(RentalOwner owner) { + this.owner = owner; + } + + public List getCategories() { + return categories; + } + + public void setCategories(List categories) { + this.categories = categories; + } + + public List getOptions() { + return options; + } + + public void setOptions(List options) { + this.options = options; + } + + public ReadableProductType getType() { + return type; + } + + public void setType(ReadableProductType type) { + this.type = type; + } + + public ReadableProductPrice getProductPrice() { + return productPrice; + } + + public void setProductPrice(ReadableProductPrice productPrice) { + this.productPrice = productPrice; + } + + public List getProperties() { + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } + + public List getVariants() { + return variants; + } + + public void setVariants(List variants) { + this.variants = variants; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductFull.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductFull.java new file mode 100644 index 0000000000..bac87ea5f2 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductFull.java @@ -0,0 +1,23 @@ +package com.salesmanager.shop.model.catalog.product; + +import java.util.ArrayList; +import java.util.List; + +public class ReadableProductFull extends ReadableProduct { + + /** + * + */ + private static final long serialVersionUID = 1L; + + List descriptions = new ArrayList(); + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductList.java new file mode 100755 index 0000000000..6eb313eb61 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductList.java @@ -0,0 +1,23 @@ +package com.salesmanager.shop.model.catalog.product; + +import java.util.ArrayList; +import java.util.List; +import com.salesmanager.shop.model.entity.ReadableList; + +public class ReadableProductList extends ReadableList { + + + /** + * + */ + private static final long serialVersionUID = 1L; + + private List products = new ArrayList(); + public void setProducts(List products) { + this.products = products; + } + public List getProducts() { + return products; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductName.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductName.java new file mode 100644 index 0000000000..4b0e644584 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductName.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.catalog.product; + +import com.salesmanager.shop.model.catalog.product.product.ProductEntity; + +public class ReadableProductName extends ProductEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductPrice.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductPrice.java new file mode 100755 index 0000000000..ce58de25df --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductPrice.java @@ -0,0 +1,58 @@ +package com.salesmanager.shop.model.catalog.product; + +import java.io.Serializable; +import com.salesmanager.shop.model.entity.Entity; + +public class ReadableProductPrice extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String originalPrice; + private String finalPrice; + private boolean defaultPrice = false; + private boolean discounted = false; + private ProductPriceDescription description; + + public String getOriginalPrice() { + return originalPrice; + } + + public void setOriginalPrice(String originalPrice) { + this.originalPrice = originalPrice; + } + + public String getFinalPrice() { + return finalPrice; + } + + public void setFinalPrice(String finalPrice) { + this.finalPrice = finalPrice; + } + + public boolean isDiscounted() { + return discounted; + } + + public void setDiscounted(boolean discounted) { + this.discounted = discounted; + } + + public ProductPriceDescription getDescription() { + return description; + } + + public void setDescription(ProductPriceDescription description) { + this.description = description; + } + + public boolean isDefaultPrice() { + return defaultPrice; + } + + public void setDefaultPrice(boolean defaultPrice) { + this.defaultPrice = defaultPrice; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductPriceFull.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductPriceFull.java new file mode 100644 index 0000000000..269e8ccd3a --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductPriceFull.java @@ -0,0 +1,25 @@ +package com.salesmanager.shop.model.catalog.product; + +import java.util.ArrayList; +import java.util.List; + +public class ReadableProductPriceFull extends ReadableProductPrice { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private List descriptions = new ArrayList(); + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductReview.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductReview.java new file mode 100755 index 0000000000..4c5a1c6a8b --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/ReadableProductReview.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.catalog.product; + +import java.io.Serializable; + +import com.salesmanager.shop.model.customer.ReadableCustomer; + + +public class ReadableProductReview extends ProductReviewEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private ReadableCustomer customer; + public ReadableCustomer getCustomer() { + return customer; + } + public void setCustomer(ReadableCustomer customer) { + this.customer = customer; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/RelatedProduct.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/RelatedProduct.java new file mode 100755 index 0000000000..bdbb2afc06 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/RelatedProduct.java @@ -0,0 +1,19 @@ +package com.salesmanager.shop.model.catalog.product; + +import java.io.Serializable; + +public class RelatedProduct extends Product implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String relationShipType; //RELATED_ITEM ~ BUNDLED_ITEM + public void setRelationShipType(String relationShipType) { + this.relationShipType = relationShipType; + } + public String getRelationShipType() { + return relationShipType; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/RentalOwner.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/RentalOwner.java new file mode 100755 index 0000000000..caced18d05 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/RentalOwner.java @@ -0,0 +1,45 @@ +package com.salesmanager.shop.model.catalog.product; + +import com.salesmanager.shop.model.customer.address.Address; +import com.salesmanager.shop.model.entity.Entity; + +/** + * RENTAL customer + * @author c.samson + * + */ +public class RentalOwner extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String firstName; + private String lastName; + private Address address; + private String emailAddress; + public String getFirstName() { + return firstName; + } + public void setFirstName(String firstName) { + this.firstName = firstName; + } + public String getLastName() { + return lastName; + } + public void setLastName(String lastName) { + this.lastName = lastName; + } + public Address getAddress() { + return address; + } + public void setAddress(Address address) { + this.address = address; + } + public String getEmailAddress() { + return emailAddress; + } + public void setEmailAddress(String emailAddress) { + this.emailAddress = emailAddress; + } +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/PersistableProductAttribute.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/PersistableProductAttribute.java new file mode 100755 index 0000000000..f0ec49196e --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/PersistableProductAttribute.java @@ -0,0 +1,55 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +import java.io.Serializable; +import java.math.BigDecimal; + +import com.salesmanager.shop.model.catalog.product.attribute.api.ProductAttributeEntity; + +public class PersistableProductAttribute extends ProductAttributeEntity + implements Serializable { + + private BigDecimal productAttributeWeight; + private BigDecimal productAttributePrice; + private Long productId; + + private ProductPropertyOption option; + private PersistableProductOptionValue optionValue; + + + public void setOption(ProductPropertyOption option) { + this.option = option; + } + public ProductPropertyOption getOption() { + return option; + } + + /** + * + */ + private static final long serialVersionUID = 1L; + public BigDecimal getProductAttributeWeight() { + return productAttributeWeight; + } + public void setProductAttributeWeight(BigDecimal productAttributeWeight) { + this.productAttributeWeight = productAttributeWeight; + } + public BigDecimal getProductAttributePrice() { + return productAttributePrice; + } + public void setProductAttributePrice(BigDecimal productAttributePrice) { + this.productAttributePrice = productAttributePrice; + } + public Long getProductId() { + return productId; + } + public void setProductId(Long productId) { + this.productId = productId; + } + public PersistableProductOptionValue getOptionValue() { + return optionValue; + } + public void setOptionValue(PersistableProductOptionValue optionValue) { + this.optionValue = optionValue; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/PersistableProductOption.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/PersistableProductOption.java new file mode 100755 index 0000000000..adcf99e64a --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/PersistableProductOption.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class PersistableProductOption extends ProductOptionEntity implements + Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List descriptions = new ArrayList(); + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + public List getDescriptions() { + return descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/PersistableProductOptionValue.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/PersistableProductOptionValue.java new file mode 100755 index 0000000000..605a62456f --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/PersistableProductOptionValue.java @@ -0,0 +1,26 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.attribute.api.ProductOptionValueEntity; + +public class PersistableProductOptionValue extends ProductOptionValueEntity + implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List descriptions = new ArrayList(); + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + + public List getDescriptions() { + return descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductAttribute.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductAttribute.java new file mode 100755 index 0000000000..b7885bd3f8 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductAttribute.java @@ -0,0 +1,15 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + +public class ProductAttribute extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductAttributeValueDescription.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductAttributeValueDescription.java new file mode 100755 index 0000000000..e9d8d92971 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductAttributeValueDescription.java @@ -0,0 +1,15 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +import java.io.Serializable; + +import com.salesmanager.shop.model.catalog.NamedEntity; + +public class ProductAttributeValueDescription extends NamedEntity implements + Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductOptionDescription.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductOptionDescription.java new file mode 100755 index 0000000000..a658dc3cd7 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductOptionDescription.java @@ -0,0 +1,16 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +import java.io.Serializable; + +import com.salesmanager.shop.model.catalog.NamedEntity; + + +public class ProductOptionDescription extends NamedEntity implements + Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductOptionEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductOptionEntity.java new file mode 100755 index 0000000000..2e77f2c2b4 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductOptionEntity.java @@ -0,0 +1,28 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +import java.io.Serializable; + +public class ProductOptionEntity extends ProductPropertyOption implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private int order; + + private String type; + public void setOrder(int order) { + this.order = order; + } + public int getOrder() { + return order; + } + + public void setType(String type) { + this.type = type; + } + public String getType() { + return type; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductOptionValue.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductOptionValue.java new file mode 100755 index 0000000000..2c6a5d718d --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductOptionValue.java @@ -0,0 +1,52 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + + +public class ProductOptionValue extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String code; + private String name; + private boolean defaultValue; + private int sortOrder; + private String image; + + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public boolean isDefaultValue() { + return defaultValue; + } + public void setDefaultValue(boolean defaultValue) { + this.defaultValue = defaultValue; + } + public int getSortOrder() { + return sortOrder; + } + public void setSortOrder(int sortOrder) { + this.sortOrder = sortOrder; + } + public String getImage() { + return image; + } + public void setImage(String image) { + this.image = image; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductOptionValueDescription.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductOptionValueDescription.java new file mode 100755 index 0000000000..1ea8910d16 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductOptionValueDescription.java @@ -0,0 +1,15 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +import java.io.Serializable; + +import com.salesmanager.shop.model.catalog.NamedEntity; + +public class ProductOptionValueDescription extends NamedEntity implements + Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductPropertyOption.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductPropertyOption.java new file mode 100755 index 0000000000..eb48c963dd --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ProductPropertyOption.java @@ -0,0 +1,41 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +import java.io.Serializable; +import com.salesmanager.shop.model.entity.Entity; + + +public class ProductPropertyOption extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String code; + private String type; + private boolean readOnly; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public boolean isReadOnly() { + return readOnly; + } + + public void setReadOnly(boolean readOnly) { + this.readOnly = readOnly; + } + +} \ No newline at end of file diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductAttribute.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductAttribute.java new file mode 100755 index 0000000000..414b45edfc --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductAttribute.java @@ -0,0 +1,54 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.attribute.api.ProductAttributeEntity; + +public class ReadableProductAttribute extends ProductAttributeEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String name; + private String lang; + private String code; + private String type; + + private List attributeValues = new ArrayList(); + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getLang() { + return lang; + } + public void setLang(String lang) { + this.lang = lang; + } + public List getAttributeValues() { + return attributeValues; + } + public void setAttributeValues(List attributeValues) { + this.attributeValues = attributeValues; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductAttributeValue.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductAttributeValue.java new file mode 100755 index 0000000000..ce8de37fea --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductAttributeValue.java @@ -0,0 +1,39 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +public class ReadableProductAttributeValue extends ProductOptionValue { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String name; + private String lang; + private String description; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLang() { + return lang; + } + + public void setLang(String lang) { + this.lang = lang; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductOption.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductOption.java new file mode 100755 index 0000000000..de2882701c --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductOption.java @@ -0,0 +1,55 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionValue; + +public class ReadableProductOption extends ProductPropertyOption { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String name; + private String lang; + private boolean variant; + private List optionValues = new ArrayList(); + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLang() { + return lang; + } + + public void setLang(String lang) { + this.lang = lang; + } + + public List getOptionValues() { + return optionValues; + } + + public void setOptionValues(List optionValues) { + this.optionValues = optionValues; + } + + public boolean isVariant() { + return variant; + } + + public void setVariant(boolean variant) { + this.variant = variant; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductOptionValue.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductOptionValue.java new file mode 100755 index 0000000000..294fd73ee9 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductOptionValue.java @@ -0,0 +1,39 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +public class ReadableProductOptionValue extends ProductOptionValue { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String price; + private String image; + private String description; + + + public String getPrice() { + return price; + } + + public void setPrice(String price) { + this.price = price; + } + + public String getImage() { + return image; + } + + public void setImage(String image) { + this.image = image; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductProperty.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductProperty.java new file mode 100644 index 0000000000..ebba7fdb94 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductProperty.java @@ -0,0 +1,30 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +public class ReadableProductProperty extends ProductPropertyOption { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Property use option objects + */ + private ReadableProductOption property = null; + private ReadableProductPropertyValue propertyValue = null; + public ReadableProductOption getProperty() { + return property; + } + public void setProperty(ReadableProductOption property) { + this.property = property; + } + public ReadableProductPropertyValue getPropertyValue() { + return propertyValue; + } + public void setPropertyValue(ReadableProductPropertyValue propertyValue) { + this.propertyValue = propertyValue; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductPropertyValue.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductPropertyValue.java new file mode 100644 index 0000000000..cca2567349 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductPropertyValue.java @@ -0,0 +1,25 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +import java.util.ArrayList; +import java.util.List; + +public class ReadableProductPropertyValue extends ProductOptionValue{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + private List values = new ArrayList(); + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductVariant.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductVariant.java new file mode 100755 index 0000000000..3625afcd2f --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductVariant.java @@ -0,0 +1,47 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import com.salesmanager.shop.model.entity.Entity; + +public class ReadableProductVariant extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + //option name + private String name; + private String code; + private List options = new ArrayList(); + + public List getOptions() { + return options; + } + + public void setOptions(List options) { + this.options = options; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +public String getCode() { + return code; +} + +public void setCode(String code) { + this.code = code; +} + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductVariantValue.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductVariantValue.java new file mode 100755 index 0000000000..34b104b500 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableProductVariantValue.java @@ -0,0 +1,103 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +import java.io.Serializable; + +public class ReadableProductVariantValue implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String name; + private String code; + private int order; + private String description; + private Long option;// option id + private Long value;// option value id + + public Long getValue() { + return value; + } + + public void setValue(Long value) { + this.value = value; + } + + public Long getOption() { + return option; + } + + public void setOption(Long option) { + this.option = option; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((code == null) ? 0 : code.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((option == null) ? 0 : option.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ReadableProductVariantValue other = (ReadableProductVariantValue) obj; + if (code == null) { + if (other.code != null) + return false; + } else if (!code.equals(other.code)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (option == null) { + if (other.option != null) + return false; + } else if (!option.equals(other.option)) + return false; + return true; + } + + public int getOrder() { + return order; + } + + public void setOrder(int order) { + this.order = order; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableSelectedProductVariant.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableSelectedProductVariant.java new file mode 100755 index 0000000000..a766c91958 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/ReadableSelectedProductVariant.java @@ -0,0 +1,27 @@ +package com.salesmanager.shop.model.catalog.product.attribute; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * Input object used when selecting an item option + * @author carlsamson + * + */ +public class ReadableSelectedProductVariant implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List options = new ArrayList(); + + public List getOptions() { + return options; + } + public void setOptions(List options) { + this.options = options; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/PersistableProductOptionEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/PersistableProductOptionEntity.java new file mode 100644 index 0000000000..cd4f2bad69 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/PersistableProductOptionEntity.java @@ -0,0 +1,23 @@ +package com.salesmanager.shop.model.catalog.product.attribute.api; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.shop.model.catalog.product.attribute.ProductOptionEntity; + +public class PersistableProductOptionEntity extends ProductOptionEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List descriptions = new ArrayList(); + public List getDescriptions() { + return descriptions; + } + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/PersistableProductOptionValueEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/PersistableProductOptionValueEntity.java new file mode 100644 index 0000000000..497c3151dc --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/PersistableProductOptionValueEntity.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.catalog.product.attribute.api; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription; + +public class PersistableProductOptionValueEntity extends ProductOptionValueEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List descriptions = new ArrayList(); + public List getDescriptions() { + return descriptions; + } + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ProductAttributeEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ProductAttributeEntity.java new file mode 100755 index 0000000000..e229dd7e9a --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ProductAttributeEntity.java @@ -0,0 +1,39 @@ +package com.salesmanager.shop.model.catalog.product.attribute.api; + +import java.io.Serializable; + +import com.salesmanager.shop.model.catalog.product.attribute.ProductAttribute; + +public class ProductAttributeEntity extends ProductAttribute implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private int sortOrder; + private boolean attributeDefault=false; + private boolean attributeDisplayOnly = false; + + + public void setSortOrder(int sortOrder) { + this.sortOrder = sortOrder; + } + public int getSortOrder() { + return sortOrder; + } + public void setAttributeDefault(boolean attributeDefault) { + this.attributeDefault = attributeDefault; + } + public boolean isAttributeDefault() { + return attributeDefault; + } + + public boolean isAttributeDisplayOnly() { + return attributeDisplayOnly; + } + public void setAttributeDisplayOnly(boolean attributeDisplayOnly) { + this.attributeDisplayOnly = attributeDisplayOnly; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ProductOptionValueEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ProductOptionValueEntity.java new file mode 100755 index 0000000000..439f811079 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ProductOptionValueEntity.java @@ -0,0 +1,23 @@ +package com.salesmanager.shop.model.catalog.product.attribute.api; + +import java.io.Serializable; + +import com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValue; + +public class ProductOptionValueEntity extends ProductOptionValue implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private int order; + + public void setOrder(int order) { + this.order = order; + } + public int getOrder() { + return order; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductAttributeEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductAttributeEntity.java new file mode 100644 index 0000000000..ed60eff875 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductAttributeEntity.java @@ -0,0 +1,48 @@ +package com.salesmanager.shop.model.catalog.product.attribute.api; + +public class ReadableProductAttributeEntity extends ProductAttributeEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String productAttributeWeight; + private String productAttributePrice; + private String productAttributeUnformattedPrice; + + private ReadableProductOptionEntity option; + private ReadableProductOptionValue optionValue; + public String getProductAttributeWeight() { + return productAttributeWeight; + } + public void setProductAttributeWeight(String productAttributeWeight) { + this.productAttributeWeight = productAttributeWeight; + } + public String getProductAttributePrice() { + return productAttributePrice; + } + public void setProductAttributePrice(String productAttributePrice) { + this.productAttributePrice = productAttributePrice; + } + public ReadableProductOptionEntity getOption() { + return option; + } + public void setOption(ReadableProductOptionEntity option) { + this.option = option; + } + public ReadableProductOptionValue getOptionValue() { + return optionValue; + } + public void setOptionValue(ReadableProductOptionValue optionValue) { + this.optionValue = optionValue; + } + public String getProductAttributeUnformattedPrice() { + return productAttributeUnformattedPrice; + } + public void setProductAttributeUnformattedPrice(String productAttributeUnformattedPrice) { + this.productAttributeUnformattedPrice = productAttributeUnformattedPrice; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductAttributeList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductAttributeList.java new file mode 100644 index 0000000000..c37a064fea --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductAttributeList.java @@ -0,0 +1,25 @@ +package com.salesmanager.shop.model.catalog.product.attribute.api; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.entity.ReadableList; + +public class ReadableProductAttributeList extends ReadableList { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private List attributes = new ArrayList(); + + public List getAttributes() { + return attributes; + } + + public void setAttributes(List attributes) { + this.attributes = attributes; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionEntity.java new file mode 100644 index 0000000000..0928b44161 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionEntity.java @@ -0,0 +1,22 @@ + + +package com.salesmanager.shop.model.catalog.product.attribute.api; + +import com.salesmanager.shop.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.shop.model.catalog.product.attribute.ProductOptionEntity; + +public class ReadableProductOptionEntity extends ProductOptionEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private ProductOptionDescription description; + public ProductOptionDescription getDescription() { + return description; + } + public void setDescription(ProductOptionDescription description) { + this.description = description; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionFull.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionFull.java new file mode 100644 index 0000000000..c28577f350 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionFull.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.catalog.product.attribute.api; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.attribute.ProductOptionDescription; + +public class ReadableProductOptionFull extends ReadableProductOptionEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List descriptions = new ArrayList(); + public List getDescriptions() { + return descriptions; + } + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionList.java new file mode 100644 index 0000000000..96cab45862 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionList.java @@ -0,0 +1,25 @@ +package com.salesmanager.shop.model.catalog.product.attribute.api; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.entity.ReadableList; + +public class ReadableProductOptionList extends ReadableList { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private List options = new ArrayList(); + + public List getOptions() { + return options; + } + + public void setOptions(List options) { + this.options = options; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionValue.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionValue.java new file mode 100644 index 0000000000..9434d0ff05 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionValue.java @@ -0,0 +1,28 @@ + + +package com.salesmanager.shop.model.catalog.product.attribute.api; + +import com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription; + +public class ReadableProductOptionValue extends ProductOptionValueEntity { + + /** + * + */ + private String price; + private static final long serialVersionUID = 1L; + private ProductOptionValueDescription description; + public ProductOptionValueDescription getDescription() { + return description; + } + public void setDescription(ProductOptionValueDescription description) { + this.description = description; + } +public String getPrice() { + return price; +} +public void setPrice(String price) { + this.price = price; +} + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionValueFull.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionValueFull.java new file mode 100644 index 0000000000..a1fafb3218 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionValueFull.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.catalog.product.attribute.api; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription; + +public class ReadableProductOptionValueFull extends ReadableProductOptionValue { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List descriptions = new ArrayList(); + public List getDescriptions() { + return descriptions; + } + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionValueList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionValueList.java new file mode 100644 index 0000000000..49a47b814a --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/api/ReadableProductOptionValueList.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.catalog.product.attribute.api; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.entity.ReadableList; + +public class ReadableProductOptionValueList extends ReadableList { + + /** + * + */ + private static final long serialVersionUID = 1L; + List optionValues = new ArrayList(); + public List getOptionValues() { + return optionValues; + } + public void setOptionValues(List optionValues) { + this.optionValues = optionValues; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/optionset/PersistableProductOptionSet.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/optionset/PersistableProductOptionSet.java new file mode 100644 index 0000000000..f300f9a8f2 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/optionset/PersistableProductOptionSet.java @@ -0,0 +1,38 @@ +package com.salesmanager.shop.model.catalog.product.attribute.optionset; + +import java.util.List; + +public class PersistableProductOptionSet extends ProductOptionSetEntity{ + + + /** + * + */ + private static final long serialVersionUID = 1L; + private List optionValues; + private List productTypes; + private Long option; + + public List getOptionValues() { + return optionValues; + } + public void setOptionValues(List optionValues) { + this.optionValues = optionValues; + } + public Long getOption() { + return option; + } + public void setOption(Long option) { + this.option = option; + } + public List getProductTypes() { + return productTypes; + } + public void setProductTypes(List productTypes) { + this.productTypes = productTypes; + } + + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/optionset/ProductOptionSetEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/optionset/ProductOptionSetEntity.java new file mode 100644 index 0000000000..4d08fc0701 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/optionset/ProductOptionSetEntity.java @@ -0,0 +1,34 @@ +package com.salesmanager.shop.model.catalog.product.attribute.optionset; + +import java.io.Serializable; + +public class ProductOptionSetEntity implements Serializable { + + + /** + * + */ + private static final long serialVersionUID = 1L; + private Long id; + private String code; + private boolean readOnly; + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public boolean isReadOnly() { + return readOnly; + } + public void setReadOnly(boolean readOnly) { + this.readOnly = readOnly; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/optionset/ReadableProductOptionSet.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/optionset/ReadableProductOptionSet.java new file mode 100644 index 0000000000..6bc0ddc0c9 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/attribute/optionset/ReadableProductOptionSet.java @@ -0,0 +1,39 @@ +package com.salesmanager.shop.model.catalog.product.attribute.optionset; + +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductOption; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductOptionValue; +import com.salesmanager.shop.model.catalog.product.type.ReadableProductType; + +public class ReadableProductOptionSet extends ProductOptionSetEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private ReadableProductOption option; + private List values; + private List productTypes; + + public ReadableProductOption getOption() { + return option; + } + public void setOption(ReadableProductOption option) { + this.option = option; + } + public List getValues() { + return values; + } + public void setValues(List values) { + this.values = values; + } + public List getProductTypes() { + return productTypes; + } + public void setProductTypes(List productTypes) { + this.productTypes = productTypes; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/group/ProductGroup.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/group/ProductGroup.java new file mode 100644 index 0000000000..ae6688b1e6 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/group/ProductGroup.java @@ -0,0 +1,27 @@ +package com.salesmanager.shop.model.catalog.product.group; + +public class ProductGroup { + + private String code; + private boolean active; + private Long id; + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public boolean isActive() { + return active; + } + public void setActive(boolean active) { + this.active = active; + } + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/inventory/InventoryEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/inventory/InventoryEntity.java new file mode 100644 index 0000000000..e251f86937 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/inventory/InventoryEntity.java @@ -0,0 +1,69 @@ +package com.salesmanager.shop.model.catalog.product.inventory; + +import com.salesmanager.shop.model.entity.Entity; + +public class InventoryEntity extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private int quantity; + private String region; + private String regionVariant; + private String owner; + private String dateAvailable; + private boolean available; + private int productQuantityOrderMin = 0; + private int productQuantityOrderMax = 0; + public int getQuantity() { + return quantity; + } + public void setQuantity(int quantity) { + this.quantity = quantity; + } + public String getRegion() { + return region; + } + public void setRegion(String region) { + this.region = region; + } + public String getRegionVariant() { + return regionVariant; + } + public void setRegionVariant(String regionVariant) { + this.regionVariant = regionVariant; + } + public String getOwner() { + return owner; + } + public void setOwner(String owner) { + this.owner = owner; + } + public boolean isAvailable() { + return available; + } + public void setAvailable(boolean available) { + this.available = available; + } + public int getProductQuantityOrderMin() { + return productQuantityOrderMin; + } + public void setProductQuantityOrderMin(int productQuantityOrderMin) { + this.productQuantityOrderMin = productQuantityOrderMin; + } + public int getProductQuantityOrderMax() { + return productQuantityOrderMax; + } + public void setProductQuantityOrderMax(int productQuantityOrderMax) { + this.productQuantityOrderMax = productQuantityOrderMax; + } + public String getDateAvailable() { + return dateAvailable; + } + public void setDateAvailable(String dateAvailable) { + this.dateAvailable = dateAvailable; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/inventory/PersistableInventory.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/inventory/PersistableInventory.java new file mode 100644 index 0000000000..23c909a009 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/inventory/PersistableInventory.java @@ -0,0 +1,52 @@ +package com.salesmanager.shop.model.catalog.product.inventory; + +import java.util.List; +import com.salesmanager.shop.model.catalog.product.PersistableProductPrice; + +import javax.validation.constraints.NotNull; + +public class PersistableInventory extends InventoryEntity { + + /** + * An inventory for a given product and possibly a given variant + */ + private static final long serialVersionUID = 1L; + private String store; + @NotNull + private Long productId; + private Long variant; + private List prices; + + public String getStore() { + return store; + } + + public void setStore(String store) { + this.store = store; + } + + public List getPrices() { + return prices; + } + + public void setPrices(List prices) { + this.prices = prices; + } + + public Long getProductId() { + return productId; + } + + public void setProductId(Long productId) { + this.productId = productId; + } + + public Long getVariant() { + return variant; + } + + public void setVariant(Long instance) { + this.variant = instance; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/inventory/ReadableInventory.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/inventory/ReadableInventory.java new file mode 100644 index 0000000000..e708a17462 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/inventory/ReadableInventory.java @@ -0,0 +1,63 @@ +package com.salesmanager.shop.model.catalog.product.inventory; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.ReadableProductPrice; +import com.salesmanager.shop.model.store.ReadableMerchantStore; + +public class ReadableInventory extends InventoryEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String creationDate; + + private ReadableMerchantStore store; + private String sku; + private List prices = new ArrayList(); + private String price; + + public ReadableMerchantStore getStore() { + return store; + } + + public void setStore(ReadableMerchantStore store) { + this.store = store; + } + + public List getPrices() { + return prices; + } + + public void setPrices(List prices) { + this.prices = prices; + } + + public String getCreationDate() { + return creationDate; + } + + public void setCreationDate(String creationDate) { + this.creationDate = creationDate; + } + + public String getSku() { + return sku; + } + + public void setSku(String sku) { + this.sku = sku; + } + + public String getPrice() { + return price; + } + + public void setPrice(String price) { + this.price = price; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/inventory/ReadableInventoryList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/inventory/ReadableInventoryList.java new file mode 100644 index 0000000000..eecd7e12c3 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/inventory/ReadableInventoryList.java @@ -0,0 +1,21 @@ +package com.salesmanager.shop.model.catalog.product.inventory; + +import java.util.ArrayList; +import java.util.List; +import com.salesmanager.shop.model.entity.ReadableList; + +public class ReadableInventoryList extends ReadableList { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List inventory = new ArrayList(); + public List getInventory() { + return inventory; + } + public void setInventory(List inventory) { + this.inventory = inventory; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/PersistableProduct.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/PersistableProduct.java new file mode 100755 index 0000000000..faac0a362c --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/PersistableProduct.java @@ -0,0 +1,73 @@ +package com.salesmanager.shop.model.catalog.product.product; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import com.salesmanager.shop.model.catalog.category.Category; +import com.salesmanager.shop.model.catalog.product.PersistableImage; +import com.salesmanager.shop.model.catalog.product.ProductDescription; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductAttribute; +import com.salesmanager.shop.model.catalog.product.product.variant.PersistableProductVariant; + + + +public class PersistableProduct extends ProductEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private List descriptions = new ArrayList(); + private List attributes = new ArrayList();//persist attribute and save reference + private List images;//persist images and save reference + private List categories = new ArrayList(); + private PersistableProductInventory inventory; + private List variants = new ArrayList(); + private String type; + + public List getDescriptions() { + return descriptions; + } + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + + public List getImages() { + return images; + } + public void setImages(List images) { + this.images = images; + } + public List getCategories() { + return categories; + } + public void setCategories(List categories) { + this.categories = categories; + } + public void setAttributes(List attributes) { + this.attributes = attributes; + } + public List getAttributes() { + return attributes; + } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + public PersistableProductInventory getInventory() { + return inventory; + } + public void setInventory(PersistableProductInventory inventory) { + this.inventory = inventory; + } + public List getVariants() { + return variants; + } + public void setVariants(List variants) { + this.variants = variants; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/PersistableProductInventory.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/PersistableProductInventory.java new file mode 100644 index 0000000000..6b2c99b5fa --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/PersistableProductInventory.java @@ -0,0 +1,33 @@ +package com.salesmanager.shop.model.catalog.product.product; + +import java.io.Serializable; + +import com.salesmanager.shop.model.catalog.product.PersistableProductPrice; + +public class PersistableProductInventory implements Serializable { + + private static final long serialVersionUID = 1L; + + private String sku; + private int quantity = 0; + private PersistableProductPrice price; + public String getSku() { + return sku; + } + public void setSku(String sku) { + this.sku = sku; + } + public int getQuantity() { + return quantity; + } + public void setQuantity(int quantity) { + this.quantity = quantity; + } + public PersistableProductPrice getPrice() { + return price; + } + public void setPrice(PersistableProductPrice price) { + this.price = price; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/ProductEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/ProductEntity.java new file mode 100755 index 0000000000..8804bf5e57 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/ProductEntity.java @@ -0,0 +1,176 @@ +package com.salesmanager.shop.model.catalog.product.product; + +import java.io.Serializable; +import java.math.BigDecimal; + +import com.salesmanager.shop.model.catalog.product.Product; + +/** + * A product entity is used by services API to populate or retrieve a Product + * entity + * + * @author Carl Samson + * + */ +public class ProductEntity extends Product implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private BigDecimal price; + private int quantity = 0; + private String sku; + private boolean preOrder = false; + private boolean productVirtual = false; + private int quantityOrderMaximum = -1;// default unlimited + private int quantityOrderMinimum = 1;// default 1 + private boolean productIsFree; + + private ProductSpecification productSpecifications; + private Double rating = 0D; + private int ratingCount; + private int sortOrder; + private String refSku; + + + /** + * RENTAL additional fields + * + * @return + */ + + private int rentalDuration; + private int rentalPeriod; + + /** + * End RENTAL fields + * + * @return + */ + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public int getQuantity() { + return quantity; + } + + public void setQuantity(int quantity) { + this.quantity = quantity; + } + + public String getSku() { + return sku; + } + + public void setSku(String sku) { + this.sku = sku; + } + + + public boolean isProductIsFree() { + return productIsFree; + } + + public void setProductIsFree(boolean productIsFree) { + this.productIsFree = productIsFree; + } + + public int getSortOrder() { + return sortOrder; + } + + public void setSortOrder(int sortOrder) { + this.sortOrder = sortOrder; + } + + public void setQuantityOrderMaximum(int quantityOrderMaximum) { + this.quantityOrderMaximum = quantityOrderMaximum; + } + + public int getQuantityOrderMaximum() { + return quantityOrderMaximum; + } + + public void setProductVirtual(boolean productVirtual) { + this.productVirtual = productVirtual; + } + + public boolean isProductVirtual() { + return productVirtual; + } + + public int getQuantityOrderMinimum() { + return quantityOrderMinimum; + } + + public void setQuantityOrderMinimum(int quantityOrderMinimum) { + this.quantityOrderMinimum = quantityOrderMinimum; + } + + public int getRatingCount() { + return ratingCount; + } + + public void setRatingCount(int ratingCount) { + this.ratingCount = ratingCount; + } + + public Double getRating() { + return rating; + } + + public void setRating(Double rating) { + this.rating = rating; + } + + public boolean isPreOrder() { + return preOrder; + } + + public void setPreOrder(boolean preOrder) { + this.preOrder = preOrder; + } + + public String getRefSku() { + return refSku; + } + + public void setRefSku(String refSku) { + this.refSku = refSku; + } + + public int getRentalDuration() { + return rentalDuration; + } + + public void setRentalDuration(int rentalDuration) { + this.rentalDuration = rentalDuration; + } + + public int getRentalPeriod() { + return rentalPeriod; + } + + public void setRentalPeriod(int rentalPeriod) { + this.rentalPeriod = rentalPeriod; + } + + public ProductSpecification getProductSpecifications() { + return productSpecifications; + } + + public void setProductSpecifications(ProductSpecification productSpecifications) { + this.productSpecifications = productSpecifications; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/ProductSpecification.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/ProductSpecification.java new file mode 100755 index 0000000000..37ff035740 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/ProductSpecification.java @@ -0,0 +1,85 @@ +package com.salesmanager.shop.model.catalog.product.product; + +import java.io.Serializable; +import java.math.BigDecimal; +import com.salesmanager.shop.model.references.DimensionUnitOfMeasure; +import com.salesmanager.shop.model.references.WeightUnitOfMeasure; + +/** + * Specs weight dimension model and manufacturer + * @author carlsamson + * + */ +public class ProductSpecification implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + + private BigDecimal height; + private BigDecimal weight; + private BigDecimal length; + private BigDecimal width; + private String model; + private String manufacturer; //manufacturer code + + public String getManufacturer() { + return manufacturer; + } + public void setManufacturer(String manufacturer) { + this.manufacturer = manufacturer; + } + public String getModel() { + return model; + } + public void setModel(String model) { + this.model = model; + } + private com.salesmanager.shop.model.references.DimensionUnitOfMeasure dimensionUnitOfMeasure; + private com.salesmanager.shop.model.references.WeightUnitOfMeasure weightUnitOfMeasure; + + public BigDecimal getHeight() { + return height; + } + public void setHeight(BigDecimal height) { + this.height = height; + } + public BigDecimal getWeight() { + return weight; + } + public void setWeight(BigDecimal weight) { + this.weight = weight; + } + public BigDecimal getLength() { + return length; + } + public void setLength(BigDecimal length) { + this.length = length; + } + public BigDecimal getWidth() { + return width; + } + public void setWidth(BigDecimal width) { + this.width = width; + } + public DimensionUnitOfMeasure getDimensionUnitOfMeasure() { + return dimensionUnitOfMeasure; + } + public void setDimensionUnitOfMeasure(DimensionUnitOfMeasure dimensionUnitOfMeasure) { + this.dimensionUnitOfMeasure = dimensionUnitOfMeasure; + } + public WeightUnitOfMeasure getWeightUnitOfMeasure() { + return weightUnitOfMeasure; + } + public void setWeightUnitOfMeasure(WeightUnitOfMeasure weightUnitOfMeasure) { + this.weightUnitOfMeasure = weightUnitOfMeasure; + } + public static long getSerialversionuid() { + return serialVersionUID; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/definition/PersistableProductDefinition.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/definition/PersistableProductDefinition.java new file mode 100644 index 0000000000..22a74dffd1 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/definition/PersistableProductDefinition.java @@ -0,0 +1,68 @@ +package com.salesmanager.shop.model.catalog.product.product.definition; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.category.Category; +import com.salesmanager.shop.model.catalog.product.ProductDescription; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductAttribute; + +public class PersistableProductDefinition extends ProductDefinition { + + /** + * type and manufacturer are String type corresponding to the unique code + */ + private static final long serialVersionUID = 1L; + + private List descriptions = new ArrayList(); + private List properties = new ArrayList(); + private List categories = new ArrayList(); + private String type; + private String manufacturer; + private BigDecimal price; + private int quantity; + public List getDescriptions() { + return descriptions; + } + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + public List getProperties() { + return properties; + } + public void setProperties(List properties) { + this.properties = properties; + } + public List getCategories() { + return categories; + } + public void setCategories(List categories) { + this.categories = categories; + } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + public String getManufacturer() { + return manufacturer; + } + public void setManufacturer(String manufacturer) { + this.manufacturer = manufacturer; + } + public BigDecimal getPrice() { + return price; + } + public void setPrice(BigDecimal price) { + this.price = price; + } + public int getQuantity() { + return quantity; + } + public void setQuantity(int quantity) { + this.quantity = quantity; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/definition/ProductDefinition.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/definition/ProductDefinition.java new file mode 100644 index 0000000000..4294864aab --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/definition/ProductDefinition.java @@ -0,0 +1,84 @@ +package com.salesmanager.shop.model.catalog.product.product.definition; + +import com.salesmanager.shop.model.catalog.product.product.ProductSpecification; +import com.salesmanager.shop.model.entity.Entity; + +/** + * Applies to product version 2 management + * @author carlsamson + * + */ +public class ProductDefinition extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private boolean visible = true; + private boolean shipeable = true; + private boolean virtual = false; + private boolean canBePurchased = true; + private String dateAvailable; + private String identifier; + private String sku; //to match v1 api + private ProductSpecification productSpecifications; + private int sortOrder; + + + public boolean isVisible() { + return visible; + } + public void setVisible(boolean visible) { + this.visible = visible; + } + public String getDateAvailable() { + return dateAvailable; + } + public void setDateAvailable(String dateAvailable) { + this.dateAvailable = dateAvailable; + } + public String getIdentifier() { + return identifier; + } + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + public ProductSpecification getProductSpecifications() { + return productSpecifications; + } + public void setProductSpecifications(ProductSpecification productSpecifications) { + this.productSpecifications = productSpecifications; + } + public int getSortOrder() { + return sortOrder; + } + public void setSortOrder(int sortOrder) { + this.sortOrder = sortOrder; + } + public boolean isShipeable() { + return shipeable; + } + public void setShipeable(boolean shipeable) { + this.shipeable = shipeable; + } + public boolean isVirtual() { + return virtual; + } + public void setVirtual(boolean virtual) { + this.virtual = virtual; + } + public boolean isCanBePurchased() { + return canBePurchased; + } + public void setCanBePurchased(boolean canBePurchased) { + this.canBePurchased = canBePurchased; + } + public String getSku() { + return sku; + } + public void setSku(String sku) { + this.sku = sku; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/definition/ReadableProductDefinition.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/definition/ReadableProductDefinition.java new file mode 100644 index 0000000000..35b5b7dd36 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/definition/ReadableProductDefinition.java @@ -0,0 +1,73 @@ +package com.salesmanager.shop.model.catalog.product.product.definition; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.category.ReadableCategory; +import com.salesmanager.shop.model.catalog.manufacturer.ReadableManufacturer; +import com.salesmanager.shop.model.catalog.product.ProductDescription; +import com.salesmanager.shop.model.catalog.product.ReadableImage; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductAttribute; +import com.salesmanager.shop.model.catalog.product.inventory.ReadableInventory; +import com.salesmanager.shop.model.catalog.product.type.ReadableProductType; + +public class ReadableProductDefinition extends ProductDefinition { + + /** + * + */ + private static final long serialVersionUID = 1L; + private ReadableProductType type; + private List categories = new ArrayList(); + private ReadableManufacturer manufacturer; + private ProductDescription description = null; + private List properties = new ArrayList(); + private List images = new ArrayList(); + private ReadableInventory inventory; + + + public ReadableProductType getType() { + return type; + } + public void setType(ReadableProductType type) { + this.type = type; + } + public List getCategories() { + return categories; + } + public void setCategories(List categories) { + this.categories = categories; + } + public ReadableManufacturer getManufacturer() { + return manufacturer; + } + public void setManufacturer(ReadableManufacturer manufacturer) { + this.manufacturer = manufacturer; + } + public List getProperties() { + return properties; + } + public void setProperties(List properties) { + this.properties = properties; + } + public ProductDescription getDescription() { + return description; + } + public void setDescription(ProductDescription description) { + this.description = description; + } + public List getImages() { + return images; + } + public void setImages(List images) { + this.images = images; + } + public ReadableInventory getInventory() { + return inventory; + } + public void setInventory(ReadableInventory inventory) { + this.inventory = inventory; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/definition/ReadableProductDefinitionFull.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/definition/ReadableProductDefinitionFull.java new file mode 100644 index 0000000000..6dda32fd46 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/definition/ReadableProductDefinitionFull.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.catalog.product.product.definition; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.ProductDescription; + +public class ReadableProductDefinitionFull extends ReadableProductDefinition { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List descriptions = new ArrayList(); + public List getDescriptions() { + return descriptions; + } + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variant/PersistableProductVariant.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variant/PersistableProductVariant.java new file mode 100644 index 0000000000..1c9943c12f --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variant/PersistableProductVariant.java @@ -0,0 +1,60 @@ +package com.salesmanager.shop.model.catalog.product.product.variant; + +import com.salesmanager.shop.model.catalog.product.product.PersistableProductInventory; + +public class PersistableProductVariant extends ProductVariant { + + private static final long serialVersionUID = 1L; + + private Long variation; + private Long variationValue; + + private String variationCode; + private String variationValueCode; + + private PersistableProductInventory inventory; + + public Long getVariation() { + return variation; + } + + public void setVariation(Long variation) { + this.variation = variation; + } + + public Long getVariationValue() { + return variationValue; + } + + public void setVariationValue(Long variationValue) { + this.variationValue = variationValue; + } + + public String getVariationCode() { + return variationCode; + } + + public void setVariationCode(String variationCode) { + this.variationCode = variationCode; + } + + public String getVariationValueCode() { + return variationValueCode; + } + + public void setVariationValueCode(String variationValueCode) { + this.variationValueCode = variationValueCode; + } + + public PersistableProductInventory getInventory() { + return inventory; + } + + public void setInventory(PersistableProductInventory inventory) { + this.inventory = inventory; + } + + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variant/ProductVariant.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variant/ProductVariant.java new file mode 100644 index 0000000000..701916dd71 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variant/ProductVariant.java @@ -0,0 +1,64 @@ +package com.salesmanager.shop.model.catalog.product.product.variant; + +import com.salesmanager.shop.model.catalog.product.Product; + +public class ProductVariant extends Product { + + private static final long serialVersionUID = 1L; + private String store; + /** use product id or sku **/ + private Long productId; + private String sku; + /** **/ + private boolean available; + private String dateAvailable; + private int sortOrder; + + private boolean defaultSelection; + + public String getStore() { + return store; + } + public void setStore(String store) { + this.store = store; + } + public boolean isDefaultSelection() { + return defaultSelection; + } + public void setDefaultSelection(boolean defaultSelection) { + this.defaultSelection = defaultSelection; + } + public Long getProductId() { + return productId; + } + public void setProductId(Long productId) { + this.productId = productId; + } + public String getSku() { + return sku; + } + public void setSku(String sku) { + this.sku = sku; + } + public boolean isAvailable() { + return available; + } + public void setAvailable(boolean available) { + this.available = available; + } + public String getDateAvailable() { + return dateAvailable; + } + public void setDateAvailable(String dateAvailable) { + this.dateAvailable = dateAvailable; + } + public int getSortOrder() { + return sortOrder; + } + public void setSortOrder(int sortOrder) { + this.sortOrder = sortOrder; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variant/ReadableProductVariant.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variant/ReadableProductVariant.java new file mode 100644 index 0000000000..fe506bc805 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variant/ReadableProductVariant.java @@ -0,0 +1,51 @@ +package com.salesmanager.shop.model.catalog.product.product.variant; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.ReadableImage; +import com.salesmanager.shop.model.catalog.product.inventory.ReadableInventory; +import com.salesmanager.shop.model.catalog.product.variation.ReadableProductVariation; + +public class ReadableProductVariant extends ProductVariant { + + private static final long serialVersionUID = 1L; + + private ReadableProductVariation variation; + private ReadableProductVariation variationValue; + private String code; + private List images = new ArrayList(); + private List inventory = new ArrayList(); + + public ReadableProductVariation getVariation() { + return variation; + } + public void setVariation(ReadableProductVariation variation) { + this.variation = variation; + } + public ReadableProductVariation getVariationValue() { + return variationValue; + } + public void setVariationValue(ReadableProductVariation variationValue) { + this.variationValue = variationValue; + } + public List getImages() { + return images; + } + public void setImages(List images) { + this.images = images; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public List getInventory() { + return inventory; + } + public void setInventory(List inventory) { + this.inventory = inventory; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variantGroup/PersistableProductVariantGroup.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variantGroup/PersistableProductVariantGroup.java new file mode 100644 index 0000000000..a57c4a0697 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variantGroup/PersistableProductVariantGroup.java @@ -0,0 +1,19 @@ +package com.salesmanager.shop.model.catalog.product.product.variantGroup; + +import java.util.List; + +public class PersistableProductVariantGroup extends ProductVariantGroup { + + private static final long serialVersionUID = 1L; + + List productVariants = null; + + public List getproductVariants() { + return productVariants; + } + + public void setproductVariants(List productVariants) { + this.productVariants = productVariants; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variantGroup/ProductVariantGroup.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variantGroup/ProductVariantGroup.java new file mode 100644 index 0000000000..eaffa23bf5 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variantGroup/ProductVariantGroup.java @@ -0,0 +1,8 @@ +package com.salesmanager.shop.model.catalog.product.product.variantGroup; +import com.salesmanager.shop.model.entity.Entity; + +public class ProductVariantGroup extends Entity { + + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variantGroup/ReadableProductVariantGroup.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variantGroup/ReadableProductVariantGroup.java new file mode 100644 index 0000000000..fc7f01c207 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/product/variantGroup/ReadableProductVariantGroup.java @@ -0,0 +1,29 @@ +package com.salesmanager.shop.model.catalog.product.product.variantGroup; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.ReadableImage; +import com.salesmanager.shop.model.catalog.product.product.variant.ReadableProductVariant; + +public class ReadableProductVariantGroup extends ProductVariantGroup { + + private static final long serialVersionUID = 1L; + + List images = new ArrayList(); + + private List productVariants = new ArrayList(); + public List getproductVariants() { + return productVariants; + } + public void setproductVariants(List productVariants) { + this.productVariants = productVariants; + } + public List getImages() { + return images; + } + public void setImages(List images) { + this.images = images; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/PersistableProductType.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/PersistableProductType.java new file mode 100644 index 0000000000..3a1935f029 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/PersistableProductType.java @@ -0,0 +1,19 @@ +package com.salesmanager.shop.model.catalog.product.type; + +import java.util.List; + +public class PersistableProductType extends ProductTypeEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List descriptions; + public List getDescriptions() { + return descriptions; + } + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/ProductTypeDescription.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/ProductTypeDescription.java new file mode 100644 index 0000000000..458bc49f5e --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/ProductTypeDescription.java @@ -0,0 +1,12 @@ +package com.salesmanager.shop.model.catalog.product.type; + +import com.salesmanager.shop.model.catalog.NamedEntity; + +public class ProductTypeDescription extends NamedEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/ProductTypeEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/ProductTypeEntity.java new file mode 100644 index 0000000000..fdadc9e7c9 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/ProductTypeEntity.java @@ -0,0 +1,43 @@ +package com.salesmanager.shop.model.catalog.product.type; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + +public class ProductTypeEntity extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String code; + private boolean visible; + boolean allowAddToCart; + + public boolean isAllowAddToCart() { + return allowAddToCart; + } + + public void setAllowAddToCart(boolean allowAddToCart) { + this.allowAddToCart = allowAddToCart; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public boolean isVisible() { + return visible; + } + + public void setVisible(boolean visible) { + this.visible = visible; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/ReadableProductType.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/ReadableProductType.java new file mode 100644 index 0000000000..cd798d46be --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/ReadableProductType.java @@ -0,0 +1,19 @@ +package com.salesmanager.shop.model.catalog.product.type; + +public class ReadableProductType extends ProductTypeEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private ProductTypeDescription description; + + public ProductTypeDescription getDescription() { + return description; + } + + public void setDescription(ProductTypeDescription description) { + this.description = description; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/ReadableProductTypeFull.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/ReadableProductTypeFull.java new file mode 100644 index 0000000000..7517e5af02 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/ReadableProductTypeFull.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.catalog.product.type; + +import java.util.List; + +public class ReadableProductTypeFull extends ReadableProductType { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private List descriptions; + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/ReadableProductTypeList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/ReadableProductTypeList.java new file mode 100644 index 0000000000..7341668a84 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/type/ReadableProductTypeList.java @@ -0,0 +1,25 @@ +package com.salesmanager.shop.model.catalog.product.type; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.entity.ReadableList; + +public class ReadableProductTypeList extends ReadableList { + + /** + * + */ + private static final long serialVersionUID = 1L; + + List list = new ArrayList(); + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/variation/PersistableProductVariation.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/variation/PersistableProductVariation.java new file mode 100644 index 0000000000..dd9a01b8ea --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/variation/PersistableProductVariation.java @@ -0,0 +1,31 @@ +package com.salesmanager.shop.model.catalog.product.variation; + +/** + * A Variant + * @author carlsamson + * + */ +public class PersistableProductVariation extends ProductVariationEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private Long option = null; + private Long optionValue = null; + public Long getOption() { + return option; + } + public void setOption(Long option) { + this.option = option; + } + public Long getOptionValue() { + return optionValue; + } + public void setOptionValue(Long optionValue) { + this.optionValue = optionValue; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/variation/ProductVariationEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/variation/ProductVariationEntity.java new file mode 100644 index 0000000000..eb85675c6b --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/variation/ProductVariationEntity.java @@ -0,0 +1,42 @@ +package com.salesmanager.shop.model.catalog.product.variation; + +import com.salesmanager.shop.model.entity.Entity; + +public class ProductVariationEntity extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String code;//sku + private String date; + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + + private int sortOrder; + + private boolean defaultValue = false; + public int getSortOrder() { + return sortOrder; + } + public void setSortOrder(int sortOrder) { + this.sortOrder = sortOrder; + } + public boolean isDefaultValue() { + return defaultValue; + } + public void setDefaultValue(boolean defaultValue) { + this.defaultValue = defaultValue; + } + public String getDate() { + return date; + } + public void setDate(String date) { + this.date = date; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/variation/ReadableProductVariation.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/variation/ReadableProductVariation.java new file mode 100644 index 0000000000..7e5645dcfb --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/catalog/product/variation/ReadableProductVariation.java @@ -0,0 +1,28 @@ +package com.salesmanager.shop.model.catalog.product.variation; + +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductOption; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductOptionValue; + +public class ReadableProductVariation extends ProductVariationEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + ReadableProductOption option = null; + ReadableProductOptionValue optionValue = null; + public ReadableProductOption getOption() { + return option; + } + public void setOption(ReadableProductOption option) { + this.option = option; + } + public ReadableProductOptionValue getOptionValue() { + return optionValue; + } + public void setOptionValue(ReadableProductOptionValue optionValue) { + this.optionValue = optionValue; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/configuration/ConfigurationEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/configuration/ConfigurationEntity.java new file mode 100644 index 0000000000..fe7ff66c91 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/configuration/ConfigurationEntity.java @@ -0,0 +1,69 @@ +package com.salesmanager.shop.model.configuration; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.salesmanager.shop.model.entity.Entity; + +public class ConfigurationEntity extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String key = null; + private boolean active; + private String value; + private String type; + private String code; + private Map keys = new HashMap(); + private Map> integrationOptions = new HashMap>(); + + + + public String getKey() { + return key; + } + public void setKey(String key) { + this.key = key; + } + public boolean isActive() { + return active; + } + public void setActive(boolean active) { + this.active = active; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + public Map getKeys() { + return keys; + } + public void setKeys(Map keys) { + this.keys = keys; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public Map> getIntegrationOptions() { + return integrationOptions; + } + public void setIntegrationOptions(Map> integrationOptions) { + this.integrationOptions = integrationOptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/configuration/PersistableConfiguration.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/configuration/PersistableConfiguration.java new file mode 100644 index 0000000000..51ba5a1b63 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/configuration/PersistableConfiguration.java @@ -0,0 +1,10 @@ +package com.salesmanager.shop.model.configuration; + +public class PersistableConfiguration extends ConfigurationEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/configuration/ReadableConfiguration.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/configuration/ReadableConfiguration.java new file mode 100644 index 0000000000..66c3ee40ab --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/configuration/ReadableConfiguration.java @@ -0,0 +1,10 @@ +package com.salesmanager.shop.model.configuration; + +public class ReadableConfiguration extends ConfigurationEntity{ + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/Content.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/Content.java new file mode 100755 index 0000000000..7f9ec0223f --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/Content.java @@ -0,0 +1,45 @@ +package com.salesmanager.shop.model.content; + +import java.io.Serializable; +import javax.validation.constraints.NotEmpty; + +@Deprecated +public abstract class Content implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + @NotEmpty + private String name; + private String contentType; + + public Content() {} + + public Content(String name) { + this.name = name; + } + + public Content(String name, String contentType) { + this.name = name; + this.contentType = contentType; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public String getContentType() { + return contentType; + } + + public void setContentType(String contentType) { + this.contentType = contentType; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentDescriptionEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentDescriptionEntity.java new file mode 100644 index 0000000000..c2e01c5b48 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentDescriptionEntity.java @@ -0,0 +1,13 @@ +package com.salesmanager.shop.model.content; + +import com.salesmanager.shop.model.catalog.NamedEntity; + +@Deprecated +public class ContentDescriptionEntity extends NamedEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentEntity.java new file mode 100644 index 0000000000..7b19967216 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentEntity.java @@ -0,0 +1,41 @@ +package com.salesmanager.shop.model.content; + +import com.salesmanager.shop.model.entity.Entity; + +@Deprecated +public class ContentEntity extends Entity { + + private static final long serialVersionUID = 1L; + private String code; + private String contentType = "BOX"; + private boolean isDisplayedInMenu; + private boolean visible; + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getContentType() { + return contentType; + } + public void setContentType(String contentType) { + this.contentType = contentType; + } + public boolean isDisplayedInMenu() { + return isDisplayedInMenu; + } + public void setDisplayedInMenu(boolean isDisplayedInMenu) { + this.isDisplayedInMenu = isDisplayedInMenu; + } + public boolean isVisible() { + return visible; + } + public void setVisible(boolean visible) { + this.visible = visible; + } + public static long getSerialversionuid() { + return serialVersionUID; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentFile.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentFile.java new file mode 100755 index 0000000000..29797d523c --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentFile.java @@ -0,0 +1,27 @@ +package com.salesmanager.shop.model.content; + + +/** + * Model object used in webservice + * when creatin files + * @author carlsamson + * + */ +public class ContentFile extends ContentPath { + + /** + * + */ + private static final long serialVersionUID = 1L; + private byte[] file; + + + public byte[] getFile() { + return file; + } + public void setFile(byte[] file) { + this.file = file; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentFolder.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentFolder.java new file mode 100755 index 0000000000..9fbf69bfab --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentFolder.java @@ -0,0 +1,29 @@ +package com.salesmanager.shop.model.content; + +import java.util.ArrayList; +import java.util.List; + +/** + * Folder containing content + * images and other files + * @author carlsamson + * + */ +public class ContentFolder { + + private String path; + List content = new ArrayList(); + public String getPath() { + return path; + } + public void setPath(String path) { + this.path = path; + } + public List getContent() { + return content; + } + public void setContent(List content) { + this.content = content; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentImage.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentImage.java new file mode 100755 index 0000000000..95652e2e25 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentImage.java @@ -0,0 +1,13 @@ +package com.salesmanager.shop.model.content; + +public class ContentImage extends ContentPath { + + + + /** + * + */ + private static final long serialVersionUID = 1L; + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentName.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentName.java new file mode 100755 index 0000000000..196f54c871 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentName.java @@ -0,0 +1,31 @@ +package com.salesmanager.shop.model.content; + +/** + * Input Object used in REST request + * @author carlsamson + * + */ +@Deprecated +public class ContentName extends Content { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public ContentName() { + super(); + } + + public ContentName(String name) { + super(name); + } + + public ContentName(String name, String contentType) { + super(name); + } + + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentPath.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentPath.java new file mode 100755 index 0000000000..73622e9723 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentPath.java @@ -0,0 +1,20 @@ +package com.salesmanager.shop.model.content; + +public class ContentPath extends ContentName { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String path; + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentSettings.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentSettings.java new file mode 100755 index 0000000000..a0c46810ad --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ContentSettings.java @@ -0,0 +1,28 @@ +package com.salesmanager.shop.model.content; + +import java.io.Serializable; + + +/** + * System configuration settings for content management + * @author carlsamson + * + */ +public class ContentSettings implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String httpBasePath; + + public String getHttpBasePath() { + return httpBasePath; + } + + public void setHttpBasePath(String httpBasePath) { + this.httpBasePath = httpBasePath; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ObjectContent.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ObjectContent.java new file mode 100755 index 0000000000..447855e139 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ObjectContent.java @@ -0,0 +1,56 @@ +package com.salesmanager.shop.model.content; + +import com.salesmanager.shop.model.entity.ResourceUrlAccess; + +@Deprecated +public class ObjectContent extends ContentPath implements ResourceUrlAccess { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String slug; + private String metaDetails; + private String title; + private String pageContent; + private String language; + public String getPageContent() { + return pageContent; + } + public void setPageContent(String pageContent) { + this.pageContent = pageContent; + } + + public String getSlug() { + return slug; + } + + public void setSlug(String slug) { + this.slug = slug; + } + + public String getMetaDetails() { + return metaDetails; + } + + public void setMetaDetails(String metaDetails) { + this.metaDetails = metaDetails; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + public String getLanguage() { + return language; + } + public void setLanguage(String language) { + this.language = language; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/PersistableContent.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/PersistableContent.java new file mode 100755 index 0000000000..a9fe5aed98 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/PersistableContent.java @@ -0,0 +1,43 @@ +package com.salesmanager.shop.model.content; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import com.salesmanager.shop.model.entity.Entity; + +public class PersistableContent extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String code; + private boolean isDisplayedInMenu; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + + public boolean isDisplayedInMenu() { + return isDisplayedInMenu; + } + + public void setDisplayedInMenu(boolean isDisplayedInMenu) { + this.isDisplayedInMenu = isDisplayedInMenu; + } + + private List descriptions = new ArrayList(); + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/PersistableContentEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/PersistableContentEntity.java new file mode 100644 index 0000000000..e716424a7c --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/PersistableContentEntity.java @@ -0,0 +1,23 @@ +package com.salesmanager.shop.model.content; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class PersistableContentEntity extends ContentEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List descriptions = new ArrayList(); + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ReadableContent.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ReadableContent.java new file mode 100755 index 0000000000..83cb35e30f --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ReadableContent.java @@ -0,0 +1,25 @@ +package com.salesmanager.shop.model.content; + +/** + * A simple piece of content + * @author carlsamson + * + */ +@Deprecated +public class ReadableContent extends Content { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ReadableContentEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ReadableContentEntity.java new file mode 100644 index 0000000000..a893e89125 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ReadableContentEntity.java @@ -0,0 +1,18 @@ +package com.salesmanager.shop.model.content; + +@Deprecated +public class ReadableContentEntity extends ContentEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private ContentDescriptionEntity description = null; + public ContentDescriptionEntity getDescription() { + return description; + } + public void setDescription(ContentDescriptionEntity description) { + this.description = description; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ReadableContentFull.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ReadableContentFull.java new file mode 100644 index 0000000000..a05260a0dc --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ReadableContentFull.java @@ -0,0 +1,55 @@ +package com.salesmanager.shop.model.content; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.entity.Entity; + +@Deprecated +public class ReadableContentFull extends Entity { + + private String code; + private boolean visible; + private String contentType; + + private boolean isDisplayedInMenu; + + + /** + * + */ + private static final long serialVersionUID = 1L; + private List descriptions = new ArrayList(); + public List getDescriptions() { + return descriptions; + } + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + + public boolean isVisible() { + return visible; + } + public void setVisible(boolean visible) { + this.visible = visible; + } + public String getContentType() { + return contentType; + } + public void setContentType(String contentType) { + this.contentType = contentType; + } + public boolean isDisplayedInMenu() { + return isDisplayedInMenu; + } + public void setDisplayedInMenu(boolean isDisplayedInMenu) { + this.isDisplayedInMenu = isDisplayedInMenu; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ReadableContentObject.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ReadableContentObject.java new file mode 100644 index 0000000000..43a8f78283 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ReadableContentObject.java @@ -0,0 +1,33 @@ +package com.salesmanager.shop.model.content; + +public class ReadableContentObject extends ObjectContent { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private boolean isDisplayedInMenu; + private String code; + private Long id; + + public boolean isDisplayedInMenu() { + return isDisplayedInMenu; + } + public void setDisplayedInMenu(boolean isDisplayedInMenu) { + this.isDisplayedInMenu = isDisplayedInMenu; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ReadableImage.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ReadableImage.java new file mode 100755 index 0000000000..6052dd47ce --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/ReadableImage.java @@ -0,0 +1,32 @@ +package com.salesmanager.shop.model.content; + +import java.io.Serializable; + +/** + * Used for defining an image name and its path + * @author carlsamson + * + */ +public class ReadableImage implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String name; + private String path; + public String getPath() { + return path; + } + public void setPath(String path) { + this.path = path; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/box/ContentBox.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/box/ContentBox.java new file mode 100644 index 0000000000..62b51c9537 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/box/ContentBox.java @@ -0,0 +1,12 @@ +package com.salesmanager.shop.model.content.box; + +import com.salesmanager.shop.model.content.common.Content; + +public class ContentBox extends Content { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/box/PersistableContentBox.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/box/PersistableContentBox.java new file mode 100755 index 0000000000..68b1c4d955 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/box/PersistableContentBox.java @@ -0,0 +1,24 @@ +package com.salesmanager.shop.model.content.box; + +import java.util.List; + +import com.salesmanager.shop.model.content.common.ContentDescription; + +public class PersistableContentBox extends ContentBox { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private List descriptions; + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/box/ReadableContentBox.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/box/ReadableContentBox.java new file mode 100644 index 0000000000..7a47d6587b --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/box/ReadableContentBox.java @@ -0,0 +1,28 @@ +package com.salesmanager.shop.model.content.box; + +import com.salesmanager.shop.model.content.common.Content; +import com.salesmanager.shop.model.content.common.ContentDescription; + +public class ReadableContentBox extends Content { + + private ContentDescription description ; + private static final String BOX = "BOX"; + + /** + * + */ + private static final long serialVersionUID = 1L; + + public ReadableContentBox() { + super.setContentType(BOX); + } + + public ContentDescription getDescription() { + return description; + } + + public void setDescription(ContentDescription description) { + this.description = description; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/box/ReadableContentBoxFull.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/box/ReadableContentBoxFull.java new file mode 100644 index 0000000000..e4835fbe3a --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/box/ReadableContentBoxFull.java @@ -0,0 +1,24 @@ +package com.salesmanager.shop.model.content.box; + +import java.util.List; + +import com.salesmanager.shop.model.content.common.ContentDescription; + +public class ReadableContentBoxFull extends ReadableContentBox { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private List descriptions; + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/common/Content.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/common/Content.java new file mode 100644 index 0000000000..7b7f750c89 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/common/Content.java @@ -0,0 +1,41 @@ +package com.salesmanager.shop.model.content.common; + +import com.salesmanager.shop.model.entity.Entity; + +public class Content extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String code; + private boolean visible; + private String contentType; + + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public boolean isVisible() { + return visible; + } + + public void setVisible(boolean visible) { + this.visible = visible; + } + + public String getContentType() { + return contentType; + } + + public void setContentType(String contentType) { + this.contentType = contentType; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/common/ContentDescription.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/common/ContentDescription.java new file mode 100644 index 0000000000..888020bac4 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/common/ContentDescription.java @@ -0,0 +1,12 @@ +package com.salesmanager.shop.model.content.common; + +import com.salesmanager.shop.model.catalog.NamedEntity; + +public class ContentDescription extends NamedEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/page/ContentPage.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/page/ContentPage.java new file mode 100644 index 0000000000..187c6e02fc --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/page/ContentPage.java @@ -0,0 +1,19 @@ +package com.salesmanager.shop.model.content.page; + +import com.salesmanager.shop.model.content.common.Content; + +public class ContentPage extends Content { + + /** + * + */ + private static final long serialVersionUID = 1L; + private boolean linkToMenu; + public boolean isLinkToMenu() { + return linkToMenu; + } + public void setLinkToMenu(boolean linkToMenu) { + this.linkToMenu = linkToMenu; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/page/PersistableContentPage.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/page/PersistableContentPage.java new file mode 100755 index 0000000000..2ecad2d2a2 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/page/PersistableContentPage.java @@ -0,0 +1,24 @@ +package com.salesmanager.shop.model.content.page; + +import java.util.List; + +import com.salesmanager.shop.model.content.common.ContentDescription; + +public class PersistableContentPage extends ContentPage { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private List descriptions; + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/page/ReadableContentPage.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/page/ReadableContentPage.java new file mode 100644 index 0000000000..e14bc216c5 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/page/ReadableContentPage.java @@ -0,0 +1,33 @@ +package com.salesmanager.shop.model.content.page; + +import com.salesmanager.shop.model.content.common.ContentDescription; + +public class ReadableContentPage extends ContentPage { + + /** + * + */ + private static final long serialVersionUID = 1L; + + + private ContentDescription description ; + private String path; + + + public ContentDescription getDescription() { + return description; + } + + public void setDescription(ContentDescription description) { + this.description = description; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/page/ReadableContentPageFull.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/page/ReadableContentPageFull.java new file mode 100644 index 0000000000..3957364d0b --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/content/page/ReadableContentPageFull.java @@ -0,0 +1,23 @@ +package com.salesmanager.shop.model.content.page; + +import java.util.List; + +import com.salesmanager.shop.model.content.common.ContentDescription; + +public class ReadableContentPageFull extends ReadableContentPage { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List descriptions; + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/AnonymousCustomer.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/AnonymousCustomer.java new file mode 100755 index 0000000000..6a10402b6c --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/AnonymousCustomer.java @@ -0,0 +1,10 @@ +package com.salesmanager.shop.model.customer; + +public class AnonymousCustomer extends PersistableCustomer { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/BillingEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/BillingEntity.java new file mode 100644 index 0000000000..e40557fc08 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/BillingEntity.java @@ -0,0 +1,43 @@ +package com.salesmanager.shop.model.customer; + + +import com.salesmanager.shop.model.customer.address.Address; + +public class BillingEntity extends Address { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String email; + + private String countryName; + + private String provinceName; + + public String getCountryName() { + return countryName; + } + + public void setCountryName(String countryName) { + this.countryName = countryName; + } + + public String getProvinceName() { + return provinceName; + } + + public void setProvinceName(String provinceName) { + this.provinceName = provinceName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/Customer.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/Customer.java new file mode 100755 index 0000000000..24bef0166a --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/Customer.java @@ -0,0 +1,17 @@ +package com.salesmanager.shop.model.customer; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + + +public class Customer extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/CustomerEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/CustomerEntity.java new file mode 100755 index 0000000000..2962c0e33a --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/CustomerEntity.java @@ -0,0 +1,156 @@ +package com.salesmanager.shop.model.customer; + +import java.io.Serializable; + +import javax.validation.Valid; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotEmpty; + +import org.springframework.validation.annotation.Validated; + +import com.salesmanager.shop.model.customer.address.Address; + +import io.swagger.annotations.ApiModelProperty; + +public class CustomerEntity extends Customer implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @ApiModelProperty(notes = "Customer email address. Required for registration") + @Email (message="{messages.invalid.email}") + @NotEmpty(message="{NotEmpty.customer.emailAddress}") + private String emailAddress; + @Valid + @ApiModelProperty(notes = "Customer billing address") + private Address billing; + private Address delivery; + @ApiModelProperty(notes = "Customer gender M | F") + private String gender; + + @ApiModelProperty(notes = "2 letters language code en | fr | ...") + private String language; + private String firstName; + private String lastName; + + private String provider;//online, facebook ... + + + private String storeCode; + + //@ApiModelProperty(notes = "Username (use email address)") + //@NotEmpty(message="{NotEmpty.customer.userName}") + //can be email or anything else + private String userName; + + private Double rating = 0D; + private int ratingCount; + + public void setUserName(final String userName) { + this.userName = userName; + } + + public String getUserName() { + return userName; + } + + + public void setStoreCode(final String storeCode) { + this.storeCode = storeCode; + } + + + public String getStoreCode() { + return storeCode; + } + + + public void setEmailAddress(final String emailAddress) { + this.emailAddress = emailAddress; + } + + + public String getEmailAddress() { + return emailAddress; + } + + + public void setLanguage(final String language) { + this.language = language; + } + public String getLanguage() { + return language; + } + + + public Address getBilling() { + return billing; + } + public void setBilling(final Address billing) { + this.billing = billing; + } + public Address getDelivery() { + return delivery; + } + public void setDelivery(final Address delivery) { + this.delivery = delivery; + } + public void setGender(final String gender) { + this.gender = gender; + } + public String getGender() { + return gender; + } + + + public String getFirstName() { + return firstName; + } + + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + + public String getLastName() { + return lastName; + } + + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + + public int getRatingCount() { + return ratingCount; + } + + public void setRatingCount(int ratingCount) { + this.ratingCount = ratingCount; + } + + public Double getRating() { + return rating; + } + + public void setRating(Double rating) { + this.rating = rating; + } + + public String getProvider() { + return provider; + } + + public void setProvider(String provider) { + this.provider = provider; + } + + + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/CustomerPassword.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/CustomerPassword.java new file mode 100755 index 0000000000..efe51b6ab4 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/CustomerPassword.java @@ -0,0 +1,42 @@ +package com.salesmanager.shop.model.customer; + +import java.io.Serializable; +import javax.validation.constraints.Size; +import javax.validation.constraints.NotEmpty; +import com.salesmanager.shop.validation.FieldMatch; + +@FieldMatch.List({ + @FieldMatch(first="password",second="checkPassword",message="password.notequal") +}) +public class CustomerPassword implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + @NotEmpty( message="{currentpassword.not.empty}") + private String currentPassword; + @Size(min=6, message="{newpassword.not.empty}") + private String password; + @Size(min=6, message="{repeatpassword.not.empty}") + private String checkPassword; + public String getCurrentPassword() { + return currentPassword; + } + public void setCurrentPassword(String currentPassword) { + this.currentPassword = currentPassword; + } + public String getPassword() { + return password; + } + public void setPassword(String password) { + this.password = password; + } + public String getCheckPassword() { + return checkPassword; + } + public void setCheckPassword(String checkPassword) { + this.checkPassword = checkPassword; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/CustomerReviewEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/CustomerReviewEntity.java new file mode 100755 index 0000000000..589ce19236 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/CustomerReviewEntity.java @@ -0,0 +1,56 @@ +package com.salesmanager.shop.model.customer; + +import java.io.Serializable; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +import javax.validation.constraints.NotEmpty; + +import com.salesmanager.shop.model.entity.ShopEntity; + + +public class CustomerReviewEntity extends ShopEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + @NotEmpty + private String description; + private Long customerId;//review creator + private String date; + + @NotNull + @Min(1) + @Max(5) + private Double rating; + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + public Double getRating() { + return rating; + } + public void setRating(Double rating) { + this.rating = rating; + } + public String getDate() { + return date; + } + public void setDate(String date) { + this.date = date; + } + public Long getCustomerId() { + return customerId; + } + public void setCustomerId(Long customerId) { + this.customerId = customerId; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/DeliveryEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/DeliveryEntity.java new file mode 100755 index 0000000000..ad4f5743b2 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/DeliveryEntity.java @@ -0,0 +1,40 @@ +package com.salesmanager.shop.model.customer; + +import java.io.Serializable; + + +import com.salesmanager.shop.model.customer.address.Address; + + +public class DeliveryEntity extends Address implements Serializable { + + + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String countryName; + + private String provinceName; + + + public String getCountryName() { + return countryName; + } + + public void setCountryName(String countryName) { + this.countryName = countryName; + } + + public String getProvinceName() { + return provinceName; + } + + public void setProvinceName(String provinceName) { + this.provinceName = provinceName; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/PersistableCustomer.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/PersistableCustomer.java new file mode 100755 index 0000000000..fa620bc8bd --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/PersistableCustomer.java @@ -0,0 +1,52 @@ +package com.salesmanager.shop.model.customer; + +import java.util.List; +import com.salesmanager.shop.model.customer.attribute.PersistableCustomerAttribute; +import com.salesmanager.shop.model.security.PersistableGroup; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + + + +@ApiModel(value="Customer", description="Customer model object") +public class PersistableCustomer extends CustomerEntity { + + /** + * + */ + @ApiModelProperty(notes = "Customer password") + private String password = null; + private String repeatPassword = null; + private static final long serialVersionUID = 1L; + private List attributes; + private List groups; + + + public void setAttributes(List attributes) { + this.attributes = attributes; + } + public List getAttributes() { + return attributes; + } + + public String getPassword() { + return password; + } + public void setPassword(String password) { + this.password = password; + } + public List getGroups() { + return groups; + } + public void setGroups(List groups) { + this.groups = groups; + } + public String getRepeatPassword() { + return repeatPassword; + } + public void setRepeatPassword(String repeatPassword) { + this.repeatPassword = repeatPassword; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/PersistableCustomerReview.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/PersistableCustomerReview.java new file mode 100755 index 0000000000..34d63c37f3 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/PersistableCustomerReview.java @@ -0,0 +1,19 @@ +package com.salesmanager.shop.model.customer; + +public class PersistableCustomerReview extends CustomerReviewEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private Long reviewedCustomer; + + public Long getReviewedCustomer() { + return reviewedCustomer; + } + + public void setReviewedCustomer(Long reviewedCustomer) { + this.reviewedCustomer = reviewedCustomer; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/ReadableBilling.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/ReadableBilling.java new file mode 100644 index 0000000000..6befab1071 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/ReadableBilling.java @@ -0,0 +1,10 @@ +package com.salesmanager.shop.model.customer; + +public class ReadableBilling extends BillingEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/ReadableCustomer.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/ReadableCustomer.java new file mode 100755 index 0000000000..d23337fb59 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/ReadableCustomer.java @@ -0,0 +1,33 @@ +package com.salesmanager.shop.model.customer; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.customer.attribute.ReadableCustomerAttribute; +import com.salesmanager.shop.model.security.ReadableGroup; + + +public class ReadableCustomer extends CustomerEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List attributes = new ArrayList(); + private List groups = new ArrayList(); + + public void setAttributes(List attributes) { + this.attributes = attributes; + } + public List getAttributes() { + return attributes; + } + public List getGroups() { + return groups; + } + public void setGroups(List groups) { + this.groups = groups; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/ReadableCustomerReview.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/ReadableCustomerReview.java new file mode 100755 index 0000000000..6ec2af4534 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/ReadableCustomerReview.java @@ -0,0 +1,18 @@ +package com.salesmanager.shop.model.customer; + +public class ReadableCustomerReview extends CustomerReviewEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private ReadableCustomer reviewedCustomer; + public ReadableCustomer getReviewedCustomer() { + return reviewedCustomer; + } + public void setReviewedCustomer(ReadableCustomer reviewedCustomer) { + this.reviewedCustomer = reviewedCustomer; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/ReadableDelivery.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/ReadableDelivery.java new file mode 100755 index 0000000000..c2335160bf --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/ReadableDelivery.java @@ -0,0 +1,10 @@ +package com.salesmanager.shop.model.customer; + +public class ReadableDelivery extends DeliveryEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/SecuredCustomer.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/SecuredCustomer.java new file mode 100755 index 0000000000..fcbfc71ebb --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/SecuredCustomer.java @@ -0,0 +1,49 @@ +package com.salesmanager.shop.model.customer; + +import java.io.Serializable; +import javax.validation.constraints.Size; +import com.salesmanager.shop.validation.FieldMatch; + + +@FieldMatch.List({ + @FieldMatch(first="password",second="checkPassword",message="password.notequal") + +}) +public class SecuredCustomer extends PersistableCustomer implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + + + @Size(min=6, message="{registration.password.not.empty}") + private String password; + + @Size(min=6, message="{registration.password.not.empty}") + private String checkPassword; + + + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getCheckPassword() + { + return checkPassword; + } + + public void setCheckPassword( String checkPassword ) + { + this.checkPassword = checkPassword; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/SecuredShopPersistableCustomer.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/SecuredShopPersistableCustomer.java new file mode 100755 index 0000000000..9c83b5ac49 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/SecuredShopPersistableCustomer.java @@ -0,0 +1,24 @@ +package com.salesmanager.shop.model.customer; + + +public class SecuredShopPersistableCustomer extends SecuredCustomer { + + /** + * + */ + private static final long serialVersionUID = 1L; + + + private String checkPassword; + + + public String getCheckPassword() { + return checkPassword; + } + public void setCheckPassword(String checkPassword) { + this.checkPassword = checkPassword; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/UserAlreadyExistException.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/UserAlreadyExistException.java new file mode 100755 index 0000000000..ca0fd15f00 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/UserAlreadyExistException.java @@ -0,0 +1,13 @@ +package com.salesmanager.shop.model.customer; + +public class UserAlreadyExistException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + public UserAlreadyExistException(String message) { + super(message,null); + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/address/Address.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/address/Address.java new file mode 100755 index 0000000000..254c94c858 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/address/Address.java @@ -0,0 +1,168 @@ +package com.salesmanager.shop.model.customer.address; + +import java.io.Serializable; + +import io.swagger.annotations.ApiModelProperty; + + +/** + * Customer or someone address + * @author carlsamson + * + */ +public class Address extends AddressLocation implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @ApiModelProperty(notes = "Customer billing first name") + //@NotEmpty(message="{NotEmpty.customer.firstName}") + private String firstName; + + @ApiModelProperty(notes = "Customer billing last name") + //@NotEmpty(message="{NotEmpty.customer.lastName}") + private String lastName; + + private String bilstateOther; + + private String company; + + private String phone; + @ApiModelProperty(notes = "Customer billing or shipping address") + private String address; + @ApiModelProperty(notes = "Customer billing or shipping city") + private String city; + + + + @ApiModelProperty(notes = "Customer billing or shipping state / province (if no 2 letter codes, example: North estate)") + private String stateProvince; + private boolean billingAddress; + + private String latitude; + private String longitude; + + @ApiModelProperty(notes = "Customer billing or shipping state / province (2 letter code CA, ON...)") + private String zone;//code + + @ApiModelProperty(notes = "Customer billing or shipping country code (2 letter code US, CA, UK, IT, IN, CN...)") + //@NotEmpty(message="{NotEmpty.customer.billing.country}") + private String country;//code + + + + public void setStateProvince(String stateProvince) { + this.stateProvince = stateProvince; + } + + public void setCountry(String country) { + this.country = country; + } + + + + public String getCompany() { + return company; + } + + public void setCompany(String company) { + this.company = company; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + + + public String getStateProvince() { + return stateProvince; + } + + public String getCountry() { + return country; + } + + public void setZone(String zone) { + this.zone = zone; + } + + public String getZone() { + return zone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getPhone() { + return phone; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public boolean isBillingAddress() + { + return billingAddress; + } + + public void setBillingAddress( boolean billingAddress ) + { + this.billingAddress = billingAddress; + } + + public String getBilstateOther() + { + return bilstateOther; + } + + public void setBilstateOther( String bilstateOther ) + { + this.bilstateOther = bilstateOther; + } + + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/address/AddressLocation.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/address/AddressLocation.java new file mode 100755 index 0000000000..241995bc1c --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/address/AddressLocation.java @@ -0,0 +1,31 @@ +package com.salesmanager.shop.model.customer.address; + +import java.io.Serializable; + +public class AddressLocation implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String postalCode; + private String countryCode; + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public String getCountryCode() { + return countryCode; + } + + public void setCountryCode(String countryCode) { + this.countryCode = countryCode; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerAttribute.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerAttribute.java new file mode 100755 index 0000000000..f4cc200c63 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerAttribute.java @@ -0,0 +1,17 @@ +package com.salesmanager.shop.model.customer.attribute; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + + + +public class CustomerAttribute extends Entity implements Serializable { + + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerAttributeEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerAttributeEntity.java new file mode 100755 index 0000000000..3a7c1b4e4d --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerAttributeEntity.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.customer.attribute; + +import java.io.Serializable; + +public class CustomerAttributeEntity extends CustomerAttribute implements + Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String textValue; + public void setTextValue(String textValue) { + this.textValue = textValue; + } + public String getTextValue() { + return textValue; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOption.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOption.java new file mode 100755 index 0000000000..47a36e74e4 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOption.java @@ -0,0 +1,18 @@ +package com.salesmanager.shop.model.customer.attribute; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + + +public class CustomerOption extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOptionDescription.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOptionDescription.java new file mode 100755 index 0000000000..dd734dc537 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOptionDescription.java @@ -0,0 +1,16 @@ +package com.salesmanager.shop.model.customer.attribute; + +import java.io.Serializable; + +import com.salesmanager.shop.model.catalog.NamedEntity; + + +public class CustomerOptionDescription extends NamedEntity implements + Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOptionEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOptionEntity.java new file mode 100755 index 0000000000..032c9eca46 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOptionEntity.java @@ -0,0 +1,34 @@ +package com.salesmanager.shop.model.customer.attribute; + +import java.io.Serializable; + +public class CustomerOptionEntity extends CustomerOption implements + Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private int order; + private String code; + private String type;//TEXT|SELECT|RADIO|CHECKBOX + public void setOrder(int order) { + this.order = order; + } + public int getOrder() { + return order; + } + public void setCode(String code) { + this.code = code; + } + public String getCode() { + return code; + } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOptionValue.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOptionValue.java new file mode 100755 index 0000000000..70fed3ec4f --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOptionValue.java @@ -0,0 +1,16 @@ +package com.salesmanager.shop.model.customer.attribute; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + + +public class CustomerOptionValue extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOptionValueDescription.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOptionValueDescription.java new file mode 100755 index 0000000000..1d9be75ef6 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOptionValueDescription.java @@ -0,0 +1,15 @@ +package com.salesmanager.shop.model.customer.attribute; + +import java.io.Serializable; + +import com.salesmanager.shop.model.catalog.NamedEntity; + +public class CustomerOptionValueDescription extends NamedEntity implements + Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOptionValueEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOptionValueEntity.java new file mode 100755 index 0000000000..eb38043d30 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/CustomerOptionValueEntity.java @@ -0,0 +1,27 @@ +package com.salesmanager.shop.model.customer.attribute; + +import java.io.Serializable; + +public class CustomerOptionValueEntity extends CustomerOptionValue implements + Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private int order; + private String code; + public void setOrder(int order) { + this.order = order; + } + public int getOrder() { + return order; + } + public void setCode(String code) { + this.code = code; + } + public String getCode() { + return code; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/PersistableCustomerAttribute.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/PersistableCustomerAttribute.java new file mode 100755 index 0000000000..7881b03a0c --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/PersistableCustomerAttribute.java @@ -0,0 +1,25 @@ +package com.salesmanager.shop.model.customer.attribute; + +public class PersistableCustomerAttribute extends CustomerAttributeEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private CustomerOption customerOption; + private CustomerOptionValue customerOptionValue; + public void setCustomerOptionValue(CustomerOptionValue customerOptionValue) { + this.customerOptionValue = customerOptionValue; + } + public CustomerOptionValue getCustomerOptionValue() { + return customerOptionValue; + } + public void setCustomerOption(CustomerOption customerOption) { + this.customerOption = customerOption; + } + public CustomerOption getCustomerOption() { + return customerOption; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/PersistableCustomerOption.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/PersistableCustomerOption.java new file mode 100755 index 0000000000..c23922582b --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/PersistableCustomerOption.java @@ -0,0 +1,23 @@ +package com.salesmanager.shop.model.customer.attribute; + +import java.io.Serializable; +import java.util.List; + +public class PersistableCustomerOption extends CustomerOptionEntity + implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List descriptions; + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + + public List getDescriptions() { + return descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/PersistableCustomerOptionValue.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/PersistableCustomerOptionValue.java new file mode 100755 index 0000000000..59150bf759 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/PersistableCustomerOptionValue.java @@ -0,0 +1,23 @@ +package com.salesmanager.shop.model.customer.attribute; + +import java.io.Serializable; +import java.util.List; + +public class PersistableCustomerOptionValue extends CustomerOptionValueEntity + implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List descriptions; + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + + public List getDescriptions() { + return descriptions; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/ReadableCustomerAttribute.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/ReadableCustomerAttribute.java new file mode 100755 index 0000000000..4ca7eb614a --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/ReadableCustomerAttribute.java @@ -0,0 +1,26 @@ +package com.salesmanager.shop.model.customer.attribute; + +public class ReadableCustomerAttribute extends CustomerAttributeEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private ReadableCustomerOption customerOption; + private ReadableCustomerOptionValue customerOptionValue; + public void setCustomerOption(ReadableCustomerOption customerOption) { + this.customerOption = customerOption; + } + public ReadableCustomerOption getCustomerOption() { + return customerOption; + } + public void setCustomerOptionValue(ReadableCustomerOptionValue customerOptionValue) { + this.customerOptionValue = customerOptionValue; + } + public ReadableCustomerOptionValue getCustomerOptionValue() { + return customerOptionValue; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/ReadableCustomerOption.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/ReadableCustomerOption.java new file mode 100755 index 0000000000..7cd4547f44 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/ReadableCustomerOption.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.customer.attribute; + +import java.io.Serializable; + +public class ReadableCustomerOption extends CustomerOptionEntity + implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private CustomerOptionDescription description; + public void setDescription(CustomerOptionDescription description) { + this.description = description; + } + public CustomerOptionDescription getDescription() { + return description; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/ReadableCustomerOptionValue.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/ReadableCustomerOptionValue.java new file mode 100755 index 0000000000..7a2836ddd6 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/attribute/ReadableCustomerOptionValue.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.customer.attribute; + +import java.io.Serializable; + +public class ReadableCustomerOptionValue extends CustomerOptionValueEntity + implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private CustomerOptionValueDescription description; + public void setDescription(CustomerOptionValueDescription description) { + this.description = description; + } + public CustomerOptionValueDescription getDescription() { + return description; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/optin/CustomerOptin.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/optin/CustomerOptin.java new file mode 100755 index 0000000000..1e91574835 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/optin/CustomerOptin.java @@ -0,0 +1,14 @@ +package com.salesmanager.shop.model.customer.optin; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + +public class CustomerOptin extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/optin/CustomerOptinEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/optin/CustomerOptinEntity.java new file mode 100755 index 0000000000..4ee53524c5 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/optin/CustomerOptinEntity.java @@ -0,0 +1,38 @@ +package com.salesmanager.shop.model.customer.optin; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Email; + + +public class CustomerOptinEntity extends CustomerOptin { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String firstName; + private String lastName; + @NotNull + @Email + private String email; + public String getFirstName() { + return firstName; + } + public void setFirstName(String firstName) { + this.firstName = firstName; + } + public String getLastName() { + return lastName; + } + public void setLastName(String lastName) { + this.lastName = lastName; + } + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/optin/PersistableCustomerOptin.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/optin/PersistableCustomerOptin.java new file mode 100755 index 0000000000..596afd94c6 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/customer/optin/PersistableCustomerOptin.java @@ -0,0 +1,10 @@ +package com.salesmanager.shop.model.customer.optin; + +public class PersistableCustomerOptin extends CustomerOptinEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/CodeEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/CodeEntity.java new file mode 100644 index 0000000000..c393bc9974 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/CodeEntity.java @@ -0,0 +1,17 @@ +package com.salesmanager.shop.model.entity; + +public class CodeEntity extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String code; + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/Entity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/Entity.java new file mode 100755 index 0000000000..0777defde9 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/Entity.java @@ -0,0 +1,24 @@ +package com.salesmanager.shop.model.entity; + +import java.io.Serializable; + +public class Entity implements Serializable { + + public Entity() {} + public Entity(Long id) { + this.id = id; + } + + /** + * + */ + private static final long serialVersionUID = 1L; + private Long id = 0L; + public void setId(Long id) { + this.id = id; + } + public Long getId() { + return id; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/EntityExists.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/EntityExists.java new file mode 100755 index 0000000000..491666ab50 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/EntityExists.java @@ -0,0 +1,29 @@ +package com.salesmanager.shop.model.entity; + +import java.io.Serializable; + +public class EntityExists implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private boolean exists = false; + + public EntityExists() { + + } + + public EntityExists(boolean exists) { + this.exists = exists; + } + + public boolean isExists() { + return exists; + } + + public void setExists(boolean exists) { + this.exists = exists; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ListCriteria.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ListCriteria.java new file mode 100644 index 0000000000..7da10e740e --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ListCriteria.java @@ -0,0 +1,30 @@ +package com.salesmanager.shop.model.entity; + +/** + * Used for filtering lists + * @author carlsamson + * + */ +public class ListCriteria { + + private String name; + private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/NameEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/NameEntity.java new file mode 100644 index 0000000000..d55bb25df9 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/NameEntity.java @@ -0,0 +1,27 @@ +package com.salesmanager.shop.model.entity; + +import javax.validation.constraints.NotEmpty; + +/** + * Used as an input request object where an entity name and or id is important + * @author carlsamson + * + */ +public class NameEntity extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + @NotEmpty + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableAudit.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableAudit.java new file mode 100755 index 0000000000..16775105c2 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableAudit.java @@ -0,0 +1,26 @@ +package com.salesmanager.shop.model.entity; + +public class ReadableAudit { + + private String created; + private String modified; + private String user; + public String getCreated() { + return created; + } + public void setCreated(String created) { + this.created = created; + } + public String getModified() { + return modified; + } + public void setModified(String modified) { + this.modified = modified; + } + public String getUser() { + return user; + } + public void setUser(String user) { + this.user = user; + } +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableAuditable.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableAuditable.java new file mode 100755 index 0000000000..91da372d59 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableAuditable.java @@ -0,0 +1,8 @@ +package com.salesmanager.shop.model.entity; + +public interface ReadableAuditable { + + void setReadableAudit(ReadableAudit audit); + ReadableAudit getReadableAudit(); + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableDescription.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableDescription.java new file mode 100644 index 0000000000..fdea4ed06c --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableDescription.java @@ -0,0 +1,12 @@ +package com.salesmanager.shop.model.entity; + +import com.salesmanager.shop.model.catalog.NamedEntity; + +public class ReadableDescription extends NamedEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableEntity.java new file mode 100755 index 0000000000..77649d8f68 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableEntity.java @@ -0,0 +1,10 @@ +package com.salesmanager.shop.model.entity; + +public class ReadableEntity extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableEntityList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableEntityList.java new file mode 100644 index 0000000000..5fe955ff06 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableEntityList.java @@ -0,0 +1,21 @@ +package com.salesmanager.shop.model.entity; + +import java.util.List; + +public class ReadableEntityList extends ReadableList { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List items; + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableList.java new file mode 100755 index 0000000000..8285629dea --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ReadableList.java @@ -0,0 +1,48 @@ +package com.salesmanager.shop.model.entity; + +import java.io.Serializable; + +public abstract class ReadableList implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private int totalPages;//totalPages + private int number;//number of record in current page + private long recordsTotal;//total number of records in db + private int recordsFiltered; + + public int getTotalPages() { + return totalPages; + } + + public void setTotalPages(int totalCount) { + this.totalPages = totalCount; + } + + public long getRecordsTotal() { + return recordsTotal; + } + + public void setRecordsTotal(long recordsTotal) { + this.recordsTotal = recordsTotal; + } + + public int getRecordsFiltered() { + return recordsFiltered; + } + + public void setRecordsFiltered(int recordsFiltered) { + this.recordsFiltered = recordsFiltered; + } + + public int getNumber() { + return number; + } + + public void setNumber(int number) { + this.number = number; + } + +} \ No newline at end of file diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ResourceUrlAccess.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ResourceUrlAccess.java new file mode 100755 index 0000000000..20b3734824 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ResourceUrlAccess.java @@ -0,0 +1,13 @@ +package com.salesmanager.shop.model.entity; + +/** + * A slug is a seo type url + * @author carlsamson + * + */ +public interface ResourceUrlAccess { + + String getSlug(); + void setSlug(String slug); + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ServiceEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ServiceEntity.java new file mode 100755 index 0000000000..7721b13e6d --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ServiceEntity.java @@ -0,0 +1,21 @@ +package com.salesmanager.shop.model.entity; + +public abstract class ServiceEntity { + + private int status = 0; + private String message = null; + + public int getStatus() { + return status; + } + public void setStatus(int status) { + this.status = status; + } + public String getMessage() { + return message; + } + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ShopEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ShopEntity.java new file mode 100755 index 0000000000..e9b2a47b1d --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ShopEntity.java @@ -0,0 +1,21 @@ +package com.salesmanager.shop.model.entity; + +import java.io.Serializable; + +public abstract class ShopEntity extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String language; + + public void setLanguage(String language) { + this.language = language; + } + public String getLanguage() { + return language; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/UniqueEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/UniqueEntity.java new file mode 100755 index 0000000000..3dba4620c1 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/UniqueEntity.java @@ -0,0 +1,33 @@ +package com.salesmanager.shop.model.entity; + +import java.io.Serializable; +import javax.validation.constraints.NotNull; + +public class UniqueEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + @NotNull + private String unique; + @NotNull + private String merchant; + + public String getUnique() { + return unique; + } + + public void setUnique(String unique) { + this.unique = unique; + } + + public String getMerchant() { + return merchant; + } + + public void setMerchant(String merchant) { + this.merchant = merchant; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ValueList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ValueList.java new file mode 100755 index 0000000000..25180bd1fa --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/entity/ValueList.java @@ -0,0 +1,21 @@ +package com.salesmanager.shop.model.entity; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class ValueList implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List values = new ArrayList(); + public List getValues() { + return values; + } + public void setValues(List values) { + this.values = values; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/marketplace/MarketPlaceEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/marketplace/MarketPlaceEntity.java new file mode 100755 index 0000000000..49006d3d02 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/marketplace/MarketPlaceEntity.java @@ -0,0 +1,7 @@ +package com.salesmanager.shop.model.marketplace; + +import com.salesmanager.shop.model.entity.Entity; + +public class MarketPlaceEntity extends Entity { + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/marketplace/ReadableMarketPlace.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/marketplace/ReadableMarketPlace.java new file mode 100755 index 0000000000..65e0311795 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/marketplace/ReadableMarketPlace.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.marketplace; + +import com.salesmanager.shop.model.store.ReadableMerchantStore; + +public class ReadableMarketPlace extends MarketPlaceEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private ReadableMerchantStore store; + + public ReadableMerchantStore getStore() { + return store; + } + + public void setStore(ReadableMerchantStore store) { + this.store = store; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/marketplace/SignupStore.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/marketplace/SignupStore.java new file mode 100644 index 0000000000..18971abb3f --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/marketplace/SignupStore.java @@ -0,0 +1,124 @@ +package com.salesmanager.shop.model.marketplace; + +import java.io.Serializable; + +import javax.validation.constraints.NotEmpty; + +public class SignupStore implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @NotEmpty + private String firstName; + @NotEmpty + private String lastName; + @NotEmpty + private String email; + @NotEmpty + private String password; + @NotEmpty + private String repeatPassword; + + @NotEmpty + private String name; + @NotEmpty + private String code; + @NotEmpty + private String address; + @NotEmpty + private String city; + @NotEmpty + private String postalCode; + @NotEmpty + private String stateProvince; + @NotEmpty + private String country; + + @NotEmpty + private String returnUrl; + + + + public String getReturnUrl() { + return returnUrl; + } + public void setReturnUrl(String returnUrl) { + this.returnUrl = returnUrl; + } + public String getFirstName() { + return firstName; + } + public void setFirstName(String firstName) { + this.firstName = firstName; + } + public String getLastName() { + return lastName; + } + public void setLastName(String lastName) { + this.lastName = lastName; + } + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + public String getPassword() { + return password; + } + public void setPassword(String password) { + this.password = password; + } + public String getRepeatPassword() { + return repeatPassword; + } + public void setRepeatPassword(String repeatPassword) { + this.repeatPassword = repeatPassword; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getAddress() { + return address; + } + public void setAddress(String address) { + this.address = address; + } + public String getCity() { + return city; + } + public void setCity(String city) { + this.city = city; + } + public String getPostalCode() { + return postalCode; + } + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + public String getStateProvince() { + return stateProvince; + } + public void setStateProvince(String stateProvince) { + this.stateProvince = stateProvince; + } + public String getCountry() { + return country; + } + public void setCountry(String country) { + this.country = country; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/OrderAttribute.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/OrderAttribute.java new file mode 100755 index 0000000000..c4616f0c10 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/OrderAttribute.java @@ -0,0 +1,20 @@ +package com.salesmanager.shop.model.order; + +public class OrderAttribute { + + private String key; + private String value; + public String getKey() { + return key; + } + public void setKey(String key) { + this.key = key; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/OrderEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/OrderEntity.java new file mode 100755 index 0000000000..b84fefa8ea --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/OrderEntity.java @@ -0,0 +1,116 @@ +package com.salesmanager.shop.model.order; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import com.salesmanager.core.model.order.orderstatus.OrderStatus; +import com.salesmanager.core.model.order.payment.CreditCard; +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.shop.model.order.total.OrderTotal; +import com.salesmanager.shop.model.order.v0.Order; + +public class OrderEntity extends Order implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List totals; + private List attributes = new ArrayList(); + + private PaymentType paymentType; + private String paymentModule; + private String shippingModule; + private List previousOrderStatus; + private OrderStatus orderStatus; + private CreditCard creditCard; + private Date datePurchased; + private String currency; + private boolean customerAgreed; + private boolean confirmedAddress; + private String comments; + + public void setTotals(List totals) { + this.totals = totals; + } + public List getTotals() { + return totals; + } + public PaymentType getPaymentType() { + return paymentType; + } + public void setPaymentType(PaymentType paymentType) { + this.paymentType = paymentType; + } + public String getPaymentModule() { + return paymentModule; + } + public void setPaymentModule(String paymentModule) { + this.paymentModule = paymentModule; + } + public String getShippingModule() { + return shippingModule; + } + public void setShippingModule(String shippingModule) { + this.shippingModule = shippingModule; + } + + public CreditCard getCreditCard() { + return creditCard; + } + public void setCreditCard(CreditCard creditCard) { + this.creditCard = creditCard; + } + public Date getDatePurchased() { + return datePurchased; + } + public void setDatePurchased(Date datePurchased) { + this.datePurchased = datePurchased; + } + public void setPreviousOrderStatus(List previousOrderStatus) { + this.previousOrderStatus = previousOrderStatus; + } + public List getPreviousOrderStatus() { + return previousOrderStatus; + } + public void setOrderStatus(OrderStatus orderStatus) { + this.orderStatus = orderStatus; + } + public OrderStatus getOrderStatus() { + return orderStatus; + } + public String getCurrency() { + return currency; + } + public void setCurrency(String currency) { + this.currency = currency; + } + public boolean isCustomerAgreed() { + return customerAgreed; + } + public void setCustomerAgreed(boolean customerAgreed) { + this.customerAgreed = customerAgreed; + } + public boolean isConfirmedAddress() { + return confirmedAddress; + } + public void setConfirmedAddress(boolean confirmedAddress) { + this.confirmedAddress = confirmedAddress; + } + public String getComments() { + return comments; + } + public void setComments(String comments) { + this.comments = comments; + } + public List getAttributes() { + return attributes; + } + public void setAttributes(List attributes) { + this.attributes = attributes; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/OrderProduct.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/OrderProduct.java new file mode 100755 index 0000000000..2dce759c90 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/OrderProduct.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.order; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + + +public class OrderProduct extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String sku; + public String getSku() { + return sku; + } + public void setSku(String sku) { + this.sku = sku; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/OrderProductEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/OrderProductEntity.java new file mode 100755 index 0000000000..0644eaa33d --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/OrderProductEntity.java @@ -0,0 +1,35 @@ +package com.salesmanager.shop.model.order; + +import java.io.Serializable; + +import com.salesmanager.shop.model.catalog.product.ReadableProduct; + +public class OrderProductEntity extends OrderProduct implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private int orderedQuantity; + private ReadableProduct product; + + + + + public void setOrderedQuantity(int orderedQuantity) { + this.orderedQuantity = orderedQuantity; + } + public int getOrderedQuantity() { + return orderedQuantity; + } + public ReadableProduct getProduct() { + return product; + } + public void setProduct(ReadableProduct product) { + this.product = product; + } + + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/PersistableOrderProduct.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/PersistableOrderProduct.java new file mode 100755 index 0000000000..9409ea9d7f --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/PersistableOrderProduct.java @@ -0,0 +1,38 @@ +package com.salesmanager.shop.model.order; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.attribute.ProductAttribute; + + +public class PersistableOrderProduct extends OrderProductEntity implements + Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private BigDecimal price;//specify final price + private List attributes;//may have attributes + + + + public void setAttributes(List attributes) { + this.attributes = attributes; + } + + public List getAttributes() { + return attributes; + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ReadableOrderProduct.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ReadableOrderProduct.java new file mode 100755 index 0000000000..12be1818d5 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ReadableOrderProduct.java @@ -0,0 +1,59 @@ +package com.salesmanager.shop.model.order; + +import java.io.Serializable; +import java.util.List; + +public class ReadableOrderProduct extends OrderProductEntity implements + Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String productName; + private String price; + private String subTotal; + + private List attributes = null; + + private String sku; + private String image; + public String getProductName() { + return productName; + } + public void setProductName(String productName) { + this.productName = productName; + } + public String getSku() { + return sku; + } + public void setSku(String sku) { + this.sku = sku; + } + public String getImage() { + return image; + } + public void setImage(String image) { + this.image = image; + } + public String getPrice() { + return price; + } + public void setPrice(String price) { + this.price = price; + } + public String getSubTotal() { + return subTotal; + } + public void setSubTotal(String subTotal) { + this.subTotal = subTotal; + } + public List getAttributes() { + return attributes; + } + public void setAttributes(List attributes) { + this.attributes = attributes; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ReadableOrderProductAttribute.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ReadableOrderProductAttribute.java new file mode 100755 index 0000000000..e3e36bc873 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ReadableOrderProductAttribute.java @@ -0,0 +1,36 @@ +package com.salesmanager.shop.model.order; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + +public class ReadableOrderProductAttribute extends Entity implements Serializable { + + + /** + * + */ + private static final long serialVersionUID = 1L; + private String attributeName; + private String attributePrice; + private String attributeValue; + public String getAttributeName() { + return attributeName; + } + public void setAttributeName(String attributeName) { + this.attributeName = attributeName; + } + public String getAttributePrice() { + return attributePrice; + } + public void setAttributePrice(String attributePrice) { + this.attributePrice = attributePrice; + } + public String getAttributeValue() { + return attributeValue; + } + public void setAttributeValue(String attributeValue) { + this.attributeValue = attributeValue; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ReadableOrderProductDownload.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ReadableOrderProductDownload.java new file mode 100755 index 0000000000..25273aac53 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ReadableOrderProductDownload.java @@ -0,0 +1,61 @@ +package com.salesmanager.shop.model.order; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + +public class ReadableOrderProductDownload extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private long orderId; + + private String productName; + private String downloadUrl; + + private String fileName; + + private int downloadExpiryDays = 0; + private int downloadCount = 0; + public int getDownloadExpiryDays() { + return downloadExpiryDays; + } + public void setDownloadExpiryDays(int downloadExpiryDays) { + this.downloadExpiryDays = downloadExpiryDays; + } + public int getDownloadCount() { + return downloadCount; + } + public void setDownloadCount(int downloadCount) { + this.downloadCount = downloadCount; + } + public String getProductName() { + return productName; + } + public void setProductName(String productName) { + this.productName = productName; + } + public String getDownloadUrl() { + return downloadUrl; + } + public void setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + } + public long getOrderId() { + return orderId; + } + public void setOrderId(long orderId) { + this.orderId = orderId; + } + public String getFileName() { + return fileName; + } + public void setFileName(String fileName) { + this.fileName = fileName; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ReadableOrderTotalSummary.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ReadableOrderTotalSummary.java new file mode 100755 index 0000000000..231934856a --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ReadableOrderTotalSummary.java @@ -0,0 +1,53 @@ +package com.salesmanager.shop.model.order; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.order.total.ReadableOrderTotal; + +public class ReadableOrderTotalSummary implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String subTotal;//one time price for items + private String total;//final price + private String taxTotal;//total of taxes + + private List totals = new ArrayList();//all other fees (tax, shipping ....) + + public String getSubTotal() { + return subTotal; + } + + public void setSubTotal(String subTotal) { + this.subTotal = subTotal; + } + + public String getTotal() { + return total; + } + + public void setTotal(String total) { + this.total = total; + } + + public String getTaxTotal() { + return taxTotal; + } + + public void setTaxTotal(String taxTotal) { + this.taxTotal = taxTotal; + } + + public List getTotals() { + return totals; + } + + public void setTotals(List totals) { + this.totals = totals; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ReadableShopOrder.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ReadableShopOrder.java new file mode 100755 index 0000000000..bc1ea7e682 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ReadableShopOrder.java @@ -0,0 +1,49 @@ +package com.salesmanager.shop.model.order; + +import java.io.Serializable; +import java.util.List; + +import com.salesmanager.shop.model.order.shipping.ReadableShippingSummary; +import com.salesmanager.shop.model.order.total.ReadableOrderTotal; +import com.salesmanager.shop.model.order.v0.ReadableOrder; + +public class ReadableShopOrder extends ReadableOrder implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private ReadableShippingSummary shippingSummary; + + private String errorMessage = null;//global error message + private List subTotals;//order calculation + private String grandTotal;//grand total - order calculation + + + public String getErrorMessage() { + return errorMessage; + } + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + public String getGrandTotal() { + return grandTotal; + } + public void setGrandTotal(String grandTotal) { + this.grandTotal = grandTotal; + } + public List getSubTotals() { + return subTotals; + } + public void setSubTotals(List subTotals) { + this.subTotals = subTotals; + } + public ReadableShippingSummary getShippingSummary() { + return shippingSummary; + } + public void setShippingSummary(ReadableShippingSummary shippingSummary) { + this.shippingSummary = shippingSummary; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ShopOrder.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ShopOrder.java new file mode 100755 index 0000000000..ef3216e767 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/ShopOrder.java @@ -0,0 +1,102 @@ +package com.salesmanager.shop.model.order; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +import com.salesmanager.core.model.order.OrderTotalSummary; +import com.salesmanager.core.model.shipping.ShippingOption; +import com.salesmanager.core.model.shipping.ShippingSummary; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.shop.model.order.v0.PersistableOrder; + + +/** + * Orders saved on the website + * @author Carl Samson + * + */ +public class ShopOrder extends PersistableOrder implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List shoppingCartItems;//overrides parent API list of shoppingcartitem + private String cartCode = null; + + private OrderTotalSummary orderTotalSummary;//The order total displayed to the end user. That object will be used when committing the order + + + private ShippingSummary shippingSummary; + private ShippingOption selectedShippingOption = null;//Default selected option + + private String defaultPaymentMethodCode = null; + + + private String paymentMethodType = null;//user selected payment type + private Map payment;//user payment information + + private String errorMessage = null; + + + public void setShoppingCartItems(List shoppingCartItems) { + this.shoppingCartItems = shoppingCartItems; + } + public List getShoppingCartItems() { + return shoppingCartItems; + } + + public void setOrderTotalSummary(OrderTotalSummary orderTotalSummary) { + this.orderTotalSummary = orderTotalSummary; + } + public OrderTotalSummary getOrderTotalSummary() { + return orderTotalSummary; + } + + public ShippingSummary getShippingSummary() { + return shippingSummary; + } + public void setShippingSummary(ShippingSummary shippingSummary) { + this.shippingSummary = shippingSummary; + } + public ShippingOption getSelectedShippingOption() { + return selectedShippingOption; + } + public void setSelectedShippingOption(ShippingOption selectedShippingOption) { + this.selectedShippingOption = selectedShippingOption; + } + public String getErrorMessage() { + return errorMessage; + } + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + public String getPaymentMethodType() { + return paymentMethodType; + } + public void setPaymentMethodType(String paymentMethodType) { + this.paymentMethodType = paymentMethodType; + } + public Map getPayment() { + return payment; + } + public void setPayment(Map payment) { + this.payment = payment; + } + public String getDefaultPaymentMethodCode() { + return defaultPaymentMethodCode; + } + public void setDefaultPaymentMethodCode(String defaultPaymentMethodCode) { + this.defaultPaymentMethodCode = defaultPaymentMethodCode; + } + public String getCartCode() { + return cartCode; + } + public void setCartCode(String cartCode) { + this.cartCode = cartCode; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/history/OrderStatusHistory.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/history/OrderStatusHistory.java new file mode 100644 index 0000000000..07a4868e72 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/history/OrderStatusHistory.java @@ -0,0 +1,36 @@ +package com.salesmanager.shop.model.order.history; + +import com.salesmanager.shop.model.entity.Entity; + +public class OrderStatusHistory extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private long orderId; + private String orderStatus; + private String comments; + + + + public long getOrderId() { + return orderId; + } + public void setOrderId(long orderId) { + this.orderId = orderId; + } + public String getOrderStatus() { + return orderStatus; + } + public void setOrderStatus(String orderStatus) { + this.orderStatus = orderStatus; + } + public String getComments() { + return comments; + } + public void setComments(String comments) { + this.comments = comments; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/history/PersistableOrderStatusHistory.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/history/PersistableOrderStatusHistory.java new file mode 100644 index 0000000000..d09f007979 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/history/PersistableOrderStatusHistory.java @@ -0,0 +1,24 @@ +package com.salesmanager.shop.model.order.history; + +import com.salesmanager.core.model.order.orderstatus.OrderStatusHistory; + +public class PersistableOrderStatusHistory extends OrderStatusHistory { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String date; + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/history/ReadableOrderStatusHistory.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/history/ReadableOrderStatusHistory.java new file mode 100644 index 0000000000..540b0d0b07 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/history/ReadableOrderStatusHistory.java @@ -0,0 +1,25 @@ +package com.salesmanager.shop.model.order.history; + + + +public class ReadableOrderStatusHistory extends OrderStatusHistory { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * YYYY-mm-DD:HH mm SSS + */ + private String date; + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/shipping/ReadableShippingSummary.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/shipping/ReadableShippingSummary.java new file mode 100755 index 0000000000..90570db93e --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/shipping/ReadableShippingSummary.java @@ -0,0 +1,120 @@ +package com.salesmanager.shop.model.order.shipping; + +import com.salesmanager.core.model.shipping.ShippingOption; +import com.salesmanager.shop.model.customer.ReadableDelivery; +import com.salesmanager.shop.model.customer.address.Address; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ReadableShippingSummary implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private BigDecimal shipping; + private BigDecimal handling; + private String shippingModule; + private String shippingOption; + private boolean freeShipping; + private boolean taxOnShipping; + private boolean shippingQuote; + private String shippingText; + private String handlingText; + private ReadableDelivery delivery; + + + private ShippingOption selectedShippingOption = null;//Default selected option + private List shippingOptions = null; + + /** additional information that comes from the quote **/ + private Map quoteInformations = new HashMap(); + + + public BigDecimal getShipping() { + return shipping; + } + public void setShipping(BigDecimal shipping) { + this.shipping = shipping; + } + public BigDecimal getHandling() { + return handling; + } + public void setHandling(BigDecimal handling) { + this.handling = handling; + } + public String getShippingModule() { + return shippingModule; + } + public void setShippingModule(String shippingModule) { + this.shippingModule = shippingModule; + } + public String getShippingOption() { + return shippingOption; + } + public void setShippingOption(String shippingOption) { + this.shippingOption = shippingOption; + } + public boolean isFreeShipping() { + return freeShipping; + } + public void setFreeShipping(boolean freeShipping) { + this.freeShipping = freeShipping; + } + public boolean isTaxOnShipping() { + return taxOnShipping; + } + public void setTaxOnShipping(boolean taxOnShipping) { + this.taxOnShipping = taxOnShipping; + } + public String getShippingText() { + return shippingText; + } + public void setShippingText(String shippingText) { + this.shippingText = shippingText; + } + public String getHandlingText() { + return handlingText; + } + public void setHandlingText(String handlingText) { + this.handlingText = handlingText; + } + public static long getSerialversionuid() { + return serialVersionUID; + } + public List getShippingOptions() { + return shippingOptions; + } + public void setShippingOptions(List shippingOptions) { + this.shippingOptions = shippingOptions; + } + public ShippingOption getSelectedShippingOption() { + return selectedShippingOption; + } + public void setSelectedShippingOption(ShippingOption selectedShippingOption) { + this.selectedShippingOption = selectedShippingOption; + } + public Map getQuoteInformations() { + return quoteInformations; + } + public void setQuoteInformations(Map quoteInformations) { + this.quoteInformations = quoteInformations; + } + public Address getDelivery() { + return delivery; + } + public void setDelivery(ReadableDelivery delivery) { + this.delivery = delivery; + } + public boolean isShippingQuote() { + return shippingQuote; + } + public void setShippingQuote(boolean shippingQuote) { + this.shippingQuote = shippingQuote; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/total/OrderTotal.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/total/OrderTotal.java new file mode 100755 index 0000000000..9210d0d281 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/total/OrderTotal.java @@ -0,0 +1,61 @@ +package com.salesmanager.shop.model.order.total; + +import java.io.Serializable; +import java.math.BigDecimal; + +import com.salesmanager.shop.model.entity.Entity; + + +public class OrderTotal extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String title; + private String text; + private String code; + private int order; + private String module; + private BigDecimal value; + + + public String getTitle() { + return title; + } + public void setTitle(String title) { + this.title = title; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public int getOrder() { + return order; + } + public void setOrder(int order) { + this.order = order; + } + public String getModule() { + return module; + } + public void setModule(String module) { + this.module = module; + } + public BigDecimal getValue() { + return value; + } + public void setValue(BigDecimal value) { + this.value = value; + } + public String getText() { + return text; + } + public void setText(String text) { + this.text = text; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/total/ReadableOrderTotal.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/total/ReadableOrderTotal.java new file mode 100755 index 0000000000..1e4640e7d7 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/total/ReadableOrderTotal.java @@ -0,0 +1,26 @@ +package com.salesmanager.shop.model.order.total; + +import java.io.Serializable; + +public class ReadableOrderTotal extends OrderTotal implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String total; + private boolean discounted; + public String getTotal() { + return total; + } + public void setTotal(String total) { + this.total = total; + } + public boolean isDiscounted() { + return discounted; + } + public void setDiscounted(boolean discounted) { + this.discounted = discounted; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/total/ReadableTotal.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/total/ReadableTotal.java new file mode 100755 index 0000000000..8367f4398c --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/total/ReadableTotal.java @@ -0,0 +1,33 @@ +package com.salesmanager.shop.model.order.total; + +import java.io.Serializable; +import java.util.List; + +/** + * Serves as the order total summary calculation + * @author c.samson + * + */ +public class ReadableTotal implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private List totals; + private String grandTotal; + public List getTotals() { + return totals; + } + public void setTotals(List totals) { + this.totals = totals; + } + public String getGrandTotal() { + return grandTotal; + } + public void setGrandTotal(String grandTotal) { + this.grandTotal = grandTotal; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/PaymentEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/PaymentEntity.java new file mode 100755 index 0000000000..42ba3737fe --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/PaymentEntity.java @@ -0,0 +1,28 @@ +package com.salesmanager.shop.model.order.transaction; + +import java.io.Serializable; + +public class PaymentEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String paymentModule;//stripe|paypal|braintree|moneyorder ... + private String amount; + + public String getPaymentModule() { + return paymentModule; + } + public void setPaymentModule(String paymentModule) { + this.paymentModule = paymentModule; + } + public String getAmount() { + return amount; + } + public void setAmount(String amount) { + this.amount = amount; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/PersistablePayment.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/PersistablePayment.java new file mode 100755 index 0000000000..cba7a126e4 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/PersistablePayment.java @@ -0,0 +1,40 @@ +package com.salesmanager.shop.model.order.transaction; + +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.core.model.payments.TransactionType; + +public class PersistablePayment extends PaymentEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + @com.salesmanager.shop.validation.Enum(enumClass=PaymentType.class, ignoreCase=true) + private String paymentType; + + @com.salesmanager.shop.validation.Enum(enumClass=TransactionType.class, ignoreCase=true) + private String transactionType; + + private String paymentToken;//any token after doing init + + public String getPaymentType() { + return paymentType; + } + public void setPaymentType(String paymentType) { + this.paymentType = paymentType; + } + public String getTransactionType() { + return transactionType; + } + public void setTransactionType(String transactionType) { + this.transactionType = transactionType; + } + public String getPaymentToken() { + return paymentToken; + } + public void setPaymentToken(String paymentToken) { + this.paymentToken = paymentToken; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/PersistableTransaction.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/PersistableTransaction.java new file mode 100755 index 0000000000..ed086ad273 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/PersistableTransaction.java @@ -0,0 +1,40 @@ +package com.salesmanager.shop.model.order.transaction; + +import java.io.Serializable; +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.core.model.payments.TransactionType; + +/** + * This class is used for writing a transaction in the System + * @author c.samson + * + */ +public class PersistableTransaction extends TransactionEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @com.salesmanager.shop.validation.Enum(enumClass=PaymentType.class, ignoreCase=true) + private String paymentType; + + @com.salesmanager.shop.validation.Enum(enumClass=TransactionType.class, ignoreCase=true) + private String transactionType; + + public String getPaymentType() { + return paymentType; + } + + public void setPaymentType(String paymentType) { + this.paymentType = paymentType; + } + + public String getTransactionType() { + return transactionType; + } + + public void setTransactionType(String transactionType) { + this.transactionType = transactionType; + } +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/ReadablePayment.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/ReadablePayment.java new file mode 100755 index 0000000000..7969233cd9 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/ReadablePayment.java @@ -0,0 +1,27 @@ +package com.salesmanager.shop.model.order.transaction; + +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.core.model.payments.TransactionType; + +public class ReadablePayment extends PaymentEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private PaymentType paymentType; + private TransactionType transactionType; + public TransactionType getTransactionType() { + return transactionType; + } + public void setTransactionType(TransactionType transactionType) { + this.transactionType = transactionType; + } + public PaymentType getPaymentType() { + return paymentType; + } + public void setPaymentType(PaymentType paymentType) { + this.paymentType = paymentType; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/ReadableTransaction.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/ReadableTransaction.java new file mode 100755 index 0000000000..fbf180aa0d --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/ReadableTransaction.java @@ -0,0 +1,31 @@ +package com.salesmanager.shop.model.order.transaction; + +import java.io.Serializable; + +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.core.model.payments.TransactionType; + +public class ReadableTransaction extends TransactionEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private PaymentType paymentType; + private TransactionType transactionType; + public PaymentType getPaymentType() { + return paymentType; + } + public void setPaymentType(PaymentType paymentType) { + this.paymentType = paymentType; + } + public TransactionType getTransactionType() { + return transactionType; + } + public void setTransactionType(TransactionType transactionType) { + this.transactionType = transactionType; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/TransactionEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/TransactionEntity.java new file mode 100755 index 0000000000..c9f7aa4e07 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/transaction/TransactionEntity.java @@ -0,0 +1,50 @@ +package com.salesmanager.shop.model.order.transaction; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + +/** + * Readable version of Transaction entity object + * @author c.samson + * + */ +public class TransactionEntity extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private Long orderId; + private String details; + private String transactionDate; + private String amount; + + + public String getTransactionDate() { + return transactionDate; + } + public void setTransactionDate(String transactionDate) { + this.transactionDate = transactionDate; + } + public Long getOrderId() { + return orderId; + } + public void setOrderId(Long orderId) { + this.orderId = orderId; + } + public String getDetails() { + return details; + } + public void setDetails(String details) { + this.details = details; + } + public String getAmount() { + return amount; + } + public void setAmount(String amount) { + this.amount = amount; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v0/Order.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v0/Order.java new file mode 100755 index 0000000000..78e7f45269 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v0/Order.java @@ -0,0 +1,15 @@ +package com.salesmanager.shop.model.order.v0; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + +@Deprecated +public class Order extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v0/PersistableOrder.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v0/PersistableOrder.java new file mode 100755 index 0000000000..504ecd6aa4 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v0/PersistableOrder.java @@ -0,0 +1,49 @@ +package com.salesmanager.shop.model.order.v0; + +import java.io.Serializable; +import java.util.List; + +import com.salesmanager.shop.model.customer.PersistableCustomer; +import com.salesmanager.shop.model.order.OrderEntity; +import com.salesmanager.shop.model.order.PersistableOrderProduct; + +@Deprecated +public class PersistableOrder extends OrderEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private PersistableCustomer customer;//might already exist if id > 0, otherwise persist + private List orderProductItems; + private boolean shipToBillingAdress = true; + private boolean shipToDeliveryAddress = false; + + + public void setOrderProductItems(List orderProductItems) { + this.orderProductItems = orderProductItems; + } + public List getOrderProductItems() { + return orderProductItems; + } + public void setCustomer(PersistableCustomer customer) { + this.customer = customer; + } + public PersistableCustomer getCustomer() { + return customer; + } + public boolean isShipToBillingAdress() { + return shipToBillingAdress; + } + public void setShipToBillingAdress(boolean shipToBillingAdress) { + this.shipToBillingAdress = shipToBillingAdress; + } + public boolean isShipToDeliveryAddress() { + return shipToDeliveryAddress; + } + public void setShipToDeliveryAddress(boolean shipToDeliveryAddress) { + this.shipToDeliveryAddress = shipToDeliveryAddress; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v0/ReadableOrder.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v0/ReadableOrder.java new file mode 100755 index 0000000000..3e8b079aeb --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v0/ReadableOrder.java @@ -0,0 +1,97 @@ +package com.salesmanager.shop.model.order.v0; + +import com.salesmanager.core.model.reference.currency.Currency; +import com.salesmanager.shop.model.customer.ReadableBilling; +import com.salesmanager.shop.model.customer.ReadableCustomer; +import com.salesmanager.shop.model.customer.ReadableDelivery; +import com.salesmanager.shop.model.customer.address.Address; +import com.salesmanager.shop.model.order.OrderEntity; +import com.salesmanager.shop.model.order.ReadableOrderProduct; +import com.salesmanager.shop.model.order.total.OrderTotal; +import com.salesmanager.shop.model.store.ReadableMerchantStore; + +import java.io.Serializable; +import java.util.List; + +@Deprecated +public class ReadableOrder extends OrderEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private ReadableCustomer customer; + private List products; + private Currency currencyModel; + + private ReadableBilling billing; + private ReadableDelivery delivery; + private ReadableMerchantStore store; + + + + public void setCustomer(ReadableCustomer customer) { + this.customer = customer; + } + public ReadableCustomer getCustomer() { + return customer; + } + public OrderTotal getTotal() { + return total; + } + public void setTotal(OrderTotal total) { + this.total = total; + } + public OrderTotal getTax() { + return tax; + } + public void setTax(OrderTotal tax) { + this.tax = tax; + } + public OrderTotal getShipping() { + return shipping; + } + public void setShipping(OrderTotal shipping) { + this.shipping = shipping; + } + + public List getProducts() { + return products; + } + public void setProducts(List products) { + this.products = products; + } + + //public Currency getCurrencyModel() { + // return currencyModel; + //} + public void setCurrencyModel(Currency currencyModel) { + this.currencyModel = currencyModel; + } + + public ReadableBilling getBilling() { + return billing; + } + public void setBilling(ReadableBilling billing) { + this.billing = billing; + } + + public Address getDelivery() { + return delivery; + } + public void setDelivery(ReadableDelivery delivery) { + this.delivery = delivery; + } + + public ReadableMerchantStore getStore() { + return store; + } + public void setStore(ReadableMerchantStore store) { + this.store = store; + } + + private OrderTotal total; + private OrderTotal tax; + private OrderTotal shipping; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v0/ReadableOrderList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v0/ReadableOrderList.java new file mode 100755 index 0000000000..378ea62c8f --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v0/ReadableOrderList.java @@ -0,0 +1,26 @@ +package com.salesmanager.shop.model.order.v0; + +import java.io.Serializable; +import java.util.List; + +import com.salesmanager.shop.model.entity.ReadableList; + +@Deprecated +public class ReadableOrderList extends ReadableList implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List orders; + + + + public List getOrders() { + return orders; + } + public void setOrders(List orders) { + this.orders = orders; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/Order.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/Order.java new file mode 100755 index 0000000000..ec42a1ddd4 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/Order.java @@ -0,0 +1,56 @@ +package com.salesmanager.shop.model.order.v1; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.entity.Entity; +import com.salesmanager.shop.model.order.OrderAttribute; + +public class Order extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private boolean customerAgreement; + private String comments; + private String currency; + private List attributes = new ArrayList(); + + + public boolean isCustomerAgreement() { + return customerAgreement; + } + + public void setCustomerAgreement(boolean customerAgreement) { + this.customerAgreement = customerAgreement; + } + + public String getComments() { + return comments; + } + + public void setComments(String comments) { + this.comments = comments; + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + + public List getAttributes() { + return attributes; + } + + public void setAttributes(List attributes) { + this.attributes = attributes; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/PersistableAnonymousOrder.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/PersistableAnonymousOrder.java new file mode 100644 index 0000000000..ab7f1cefcc --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/PersistableAnonymousOrder.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.order.v1; + +import com.salesmanager.shop.model.customer.PersistableCustomer; + +public class PersistableAnonymousOrder extends PersistableOrder { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private PersistableCustomer customer; + + public PersistableCustomer getCustomer() { + return customer; + } + + public void setCustomer(PersistableCustomer customer) { + this.customer = customer; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/PersistableOrder.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/PersistableOrder.java new file mode 100755 index 0000000000..b00f225236 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/PersistableOrder.java @@ -0,0 +1,62 @@ +package com.salesmanager.shop.model.order.v1; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.salesmanager.shop.model.order.transaction.PersistablePayment; + +/** + * This object is used when processing an order from the API + * It will be used for processing the payment and as Order meta data + * @author c.samson + * + */ +public class PersistableOrder extends Order { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private PersistablePayment payment; + private Long shippingQuote; + @JsonIgnore + private Long shoppingCartId; + @JsonIgnore + private Long customerId; + + + + public Long getShoppingCartId() { + return shoppingCartId; + } + + public void setShoppingCartId(Long shoppingCartId) { + this.shoppingCartId = shoppingCartId; + } + + public Long getCustomerId() { + return customerId; + } + + public void setCustomerId(Long customerId) { + this.customerId = customerId; + } + + public PersistablePayment getPayment() { + return payment; + } + + public void setPayment(PersistablePayment payment) { + this.payment = payment; + } + + public Long getShippingQuote() { + return shippingQuote; + } + + public void setShippingQuote(Long shippingQuote) { + this.shippingQuote = shippingQuote; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/ReadableOrder.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/ReadableOrder.java new file mode 100755 index 0000000000..f08ecfe163 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/ReadableOrder.java @@ -0,0 +1,64 @@ +package com.salesmanager.shop.model.order.v1; + +import java.util.List; + +import com.salesmanager.core.model.shipping.ShippingOption; +import com.salesmanager.shop.model.customer.ReadableBilling; +import com.salesmanager.shop.model.customer.ReadableDelivery; +import com.salesmanager.shop.model.order.ReadableOrderProduct; +import com.salesmanager.shop.model.order.total.ReadableTotal; +import com.salesmanager.shop.model.order.transaction.ReadablePayment; + +public class ReadableOrder extends Order { + + /** + * + */ + private static final long serialVersionUID = 1L; + + + private ReadableBilling billing; + private ReadableDelivery delivery; + private ShippingOption shippingOption; + private ReadablePayment payment; + private ReadableTotal total; + private List products; + + public List getProducts() { + return products; + } + public void setProducts(List products) { + this.products = products; + } + public ReadableDelivery getDelivery() { + return delivery; + } + public void setDelivery(ReadableDelivery delivery) { + this.delivery = delivery; + } + public ReadablePayment getPayment() { + return payment; + } + public void setPayment(ReadablePayment payment) { + this.payment = payment; + } + public ReadableTotal getTotal() { + return total; + } + public void setTotal(ReadableTotal total) { + this.total = total; + } + public ShippingOption getShippingOption() { + return shippingOption; + } + public void setShippingOption(ShippingOption shippingOption) { + this.shippingOption = shippingOption; + } + public ReadableBilling getBilling() { + return billing; + } + public void setBilling(ReadableBilling billing) { + this.billing = billing; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/ReadableOrderConfirmation.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/ReadableOrderConfirmation.java new file mode 100644 index 0000000000..288986dfbc --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/ReadableOrderConfirmation.java @@ -0,0 +1,62 @@ +package com.salesmanager.shop.model.order.v1; + +import java.util.List; + +import com.salesmanager.shop.model.customer.ReadableBilling; +import com.salesmanager.shop.model.customer.ReadableDelivery; +import com.salesmanager.shop.model.customer.address.Address; +import com.salesmanager.shop.model.entity.Entity; +import com.salesmanager.shop.model.order.ReadableOrderProduct; +import com.salesmanager.shop.model.order.total.ReadableTotal; + +public class ReadableOrderConfirmation extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private Address billing; + private Address delivery; + private String shipping; + private String payment; + private ReadableTotal total; + private List products; + + public String getShipping() { + return shipping; + } + public void setShipping(String shipping) { + this.shipping = shipping; + } + public String getPayment() { + return payment; + } + public void setPayment(String payment) { + this.payment = payment; + } + public ReadableTotal getTotal() { + return total; + } + public void setTotal(ReadableTotal total) { + this.total = total; + } + public List getProducts() { + return products; + } + public void setProducts(List products) { + this.products = products; + } + public Address getBilling() { + return billing; + } + public void setBilling(Address billing) { + this.billing = billing; + } + public Address getDelivery() { + return delivery; + } + public void setDelivery(Address delivery) { + this.delivery = delivery; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/ReadableOrderList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/ReadableOrderList.java new file mode 100755 index 0000000000..7841948ae7 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/order/v1/ReadableOrderList.java @@ -0,0 +1,26 @@ +package com.salesmanager.shop.model.order.v1; + +import java.io.Serializable; +import java.util.List; + +import com.salesmanager.shop.model.entity.ReadableList; + + +public class ReadableOrderList extends ReadableList implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List orders; + + + + public List getOrders() { + return orders; + } + public void setOrders(List orders) { + this.orders = orders; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/Address.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/Address.java new file mode 100755 index 0000000000..6ebae5f31a --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/Address.java @@ -0,0 +1,59 @@ +package com.salesmanager.shop.model.references; + +import java.io.Serializable; + +public class Address implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + + private String stateProvince;//code + private String country;//code + private String address; + private String postalCode; + private String city; + + private boolean active = true; + public boolean isActive() { + return active; + } + public void setActive(boolean active) { + this.active = active; + } + + public String getCountry() { + return country; + } + public void setCountry(String country) { + this.country = country; + } + public String getAddress() { + return address; + } + public void setAddress(String address) { + this.address = address; + } + public String getPostalCode() { + return postalCode; + } + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + public String getCity() { + return city; + } + public void setCity(String city) { + this.city = city; + } + public String getStateProvince() { + return stateProvince; + } + public void setStateProvince(String stateProvince) { + this.stateProvince = stateProvince; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/CountryEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/CountryEntity.java new file mode 100755 index 0000000000..d5607c9473 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/CountryEntity.java @@ -0,0 +1,31 @@ +package com.salesmanager.shop.model.references; + +import com.salesmanager.shop.model.entity.Entity; + +public class CountryEntity extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String code; + private boolean supported; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public boolean isSupported() { + return supported; + } + + public void setSupported(boolean supported) { + this.supported = supported; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/DimensionUnitOfMeasure.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/DimensionUnitOfMeasure.java new file mode 100755 index 0000000000..1b11ced84e --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/DimensionUnitOfMeasure.java @@ -0,0 +1,13 @@ +package com.salesmanager.shop.model.references; + +public enum DimensionUnitOfMeasure { + /* + * cm = centimeter + * cu = cubic + * ft = feet + * in = inch + * m = meter + */ + cm, cu, ft, in, m + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/MeasureUnit.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/MeasureUnit.java new file mode 100755 index 0000000000..c0e12c1980 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/MeasureUnit.java @@ -0,0 +1,12 @@ +package com.salesmanager.shop.model.references; + +public enum MeasureUnit { + + + CM, + IN, + //METER, + //FOOT + ; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/PersistableAddress.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/PersistableAddress.java new file mode 100755 index 0000000000..589bf513c3 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/PersistableAddress.java @@ -0,0 +1,12 @@ +package com.salesmanager.shop.model.references; + + + +public class PersistableAddress extends Address { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/ReadableAddress.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/ReadableAddress.java new file mode 100755 index 0000000000..e5cbde0ae3 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/ReadableAddress.java @@ -0,0 +1,12 @@ +package com.salesmanager.shop.model.references; + +public class ReadableAddress extends Address { + + /** + * + */ + private static final long serialVersionUID = 1L; + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/ReadableCountry.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/ReadableCountry.java new file mode 100755 index 0000000000..3b4efe5126 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/ReadableCountry.java @@ -0,0 +1,32 @@ +package com.salesmanager.shop.model.references; + +import java.util.ArrayList; +import java.util.List; + +public class ReadableCountry extends CountryEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String name; + private List zones = new ArrayList(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getZones() { + return zones; + } + + public void setZones(List zones) { + this.zones = zones; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/ReadableLanguage.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/ReadableLanguage.java new file mode 100644 index 0000000000..55d60b5039 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/ReadableLanguage.java @@ -0,0 +1,26 @@ +package com.salesmanager.shop.model.references; + +import java.io.Serializable; + +public class ReadableLanguage implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String code; + private int id; + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public int getId() { + return id; + } + public void setId(int id) { + this.id = id; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/ReadableZone.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/ReadableZone.java new file mode 100755 index 0000000000..f92228633d --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/ReadableZone.java @@ -0,0 +1,17 @@ +package com.salesmanager.shop.model.references; + +public class ReadableZone extends ZoneEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String name; + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/SizeReferences.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/SizeReferences.java new file mode 100755 index 0000000000..62beee1881 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/SizeReferences.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.references; + +import java.util.List; + +public class SizeReferences { + + private List weights; + private List measures; + public List getWeights() { + return weights; + } + public void setWeights(List weights) { + this.weights = weights; + } + public List getMeasures() { + return measures; + } + public void setMeasures(List measures) { + this.measures = measures; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/WeightUnit.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/WeightUnit.java new file mode 100755 index 0000000000..6ef2ca2b22 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/WeightUnit.java @@ -0,0 +1,7 @@ +package com.salesmanager.shop.model.references; + +public enum WeightUnit { + + LB,KG,//GR + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/WeightUnitOfMeasure.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/WeightUnitOfMeasure.java new file mode 100755 index 0000000000..12cb2c94d9 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/WeightUnitOfMeasure.java @@ -0,0 +1,13 @@ +package com.salesmanager.shop.model.references; + +public enum WeightUnitOfMeasure { + /* + * g = grams + * kg = kilograms + * l = liter + * lb = pound + * T = ton + */ + g, kg, l, lb, T + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/ZoneEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/ZoneEntity.java new file mode 100755 index 0000000000..369a718ef4 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/references/ZoneEntity.java @@ -0,0 +1,26 @@ +package com.salesmanager.shop.model.references; + +import com.salesmanager.shop.model.entity.Entity; + +public class ZoneEntity extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String countryCode; + private String code; + public String getCountryCode() { + return countryCode; + } + public void setCountryCode(String countryCode) { + this.countryCode = countryCode; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/security/GroupEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/security/GroupEntity.java new file mode 100755 index 0000000000..973b16027c --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/security/GroupEntity.java @@ -0,0 +1,31 @@ +package com.salesmanager.shop.model.security; + +import java.io.Serializable; + +public class GroupEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String name; + private String type; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/security/PermissionEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/security/PermissionEntity.java new file mode 100755 index 0000000000..cb5bae4d98 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/security/PermissionEntity.java @@ -0,0 +1,26 @@ +package com.salesmanager.shop.model.security; + +import java.io.Serializable; + +public class PermissionEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private Integer id; + private String name; + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public Integer getId() { + return id; + } + public void setId(Integer id) { + this.id = id; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/security/PersistableGroup.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/security/PersistableGroup.java new file mode 100755 index 0000000000..dda84a9ec8 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/security/PersistableGroup.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.security; + +/** + * Object used for saving a group + * + * @author carlsamson + * + */ +public class PersistableGroup extends GroupEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public PersistableGroup() {} + + public PersistableGroup(String name) { + super.setName(name); + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/security/ReadableGroup.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/security/ReadableGroup.java new file mode 100755 index 0000000000..ce71aec83b --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/security/ReadableGroup.java @@ -0,0 +1,28 @@ +package com.salesmanager.shop.model.security; + +/** + * Object used for reading a group + * + * @author carlsamson + * + */ +public class ReadableGroup extends GroupEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private Long id = 0L; + + public void setId(Long id) { + this.id = id; + } + + public Long getId() { + return id; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/security/ReadablePermission.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/security/ReadablePermission.java new file mode 100755 index 0000000000..1f91e798e9 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/security/ReadablePermission.java @@ -0,0 +1,10 @@ +package com.salesmanager.shop.model.security; + +public class ReadablePermission extends PermissionEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/shipping/BoxConfiguration.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shipping/BoxConfiguration.java new file mode 100644 index 0000000000..c0aaaee97d --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shipping/BoxConfiguration.java @@ -0,0 +1,17 @@ +package com.salesmanager.shop.model.shipping; + +import java.io.Serializable; + +public class BoxConfiguration implements Serializable { + + private String code; + + private double boxWidth = 0; + private double boxHeight = 0; + private double boxLength = 0; + private double boxWeight = 0; + private double maxWeight = 0; + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/shipping/ExpeditionConfiguration.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shipping/ExpeditionConfiguration.java new file mode 100644 index 0000000000..d1362c7eb8 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shipping/ExpeditionConfiguration.java @@ -0,0 +1,36 @@ +package com.salesmanager.shop.model.shipping; + +import java.util.ArrayList; +import java.util.List; + +public class ExpeditionConfiguration { + + private boolean iternationalShipping = false; + private boolean taxOnShipping = false; + private List shipToCountry = new ArrayList(); + + public boolean isIternationalShipping() { + return iternationalShipping; + } + + public void setIternationalShipping(boolean iternationalShipping) { + this.iternationalShipping = iternationalShipping; + } + + public List getShipToCountry() { + return shipToCountry; + } + + public void setShipToCountry(List shipToCountry) { + this.shipToCountry = shipToCountry; + } + + public boolean isTaxOnShipping() { + return taxOnShipping; + } + + public void setTaxOnShipping(boolean taxOnShipping) { + this.taxOnShipping = taxOnShipping; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/shipping/ShippingConfiguration.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shipping/ShippingConfiguration.java new file mode 100644 index 0000000000..8dcd670fd7 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shipping/ShippingConfiguration.java @@ -0,0 +1,36 @@ +package com.salesmanager.shop.model.shipping; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class ShippingConfiguration implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + + + private boolean taxOnShipping = false; + private List boxConfigurations = new ArrayList(); + + + public boolean isTaxOnShipping() { + return taxOnShipping; + } + + public void setTaxOnShipping(boolean taxOnShipping) { + this.taxOnShipping = taxOnShipping; + } + + public List getBoxConfigurations() { + return boxConfigurations; + } + + public void setBoxConfigurations(List boxConfigurations) { + this.boxConfigurations = boxConfigurations; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/CartModificationException.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/CartModificationException.java new file mode 100755 index 0000000000..6c6e9f1e3e --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/CartModificationException.java @@ -0,0 +1,31 @@ +/** + * + */ +package com.salesmanager.shop.model.shoppingcart; + +/** + * @author Umesh A + * + */ +public class CartModificationException extends Exception{ + + + private static final long serialVersionUID = 679173596061770958L; + + public CartModificationException(final String msg, final Throwable cause) + { + super(msg, cause); + } + + public CartModificationException(final String msg) + { + super(msg); + } + + public CartModificationException(Throwable t) + { + super(t); + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/PersistableShoppingCartItem.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/PersistableShoppingCartItem.java new file mode 100755 index 0000000000..6d142c8f87 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/PersistableShoppingCartItem.java @@ -0,0 +1,52 @@ +package com.salesmanager.shop.model.shoppingcart; + +import java.io.Serializable; +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.attribute.ProductAttribute; + +/** + * Compatible with v1 + * @author c.samson + * + */ +public class PersistableShoppingCartItem implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String product;// or product sku (instance or product) + private int quantity; + private String promoCode; + private List attributes; + + + public String getPromoCode() { + return promoCode; + } + public void setPromoCode(String promoCode) { + this.promoCode = promoCode; + } + public int getQuantity() { + return quantity; + } + public void setQuantity(int quantity) { + this.quantity = quantity; + } + + public List getAttributes() { + return attributes; + } + public void setAttributes(List attributes) { + this.attributes = attributes; + } + public String getProduct() { + return product; + } + public void setProduct(String product) { + this.product = product; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ReadableShoppingCart.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ReadableShoppingCart.java new file mode 100755 index 0000000000..544ed9ec38 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ReadableShoppingCart.java @@ -0,0 +1,185 @@ +package com.salesmanager.shop.model.shoppingcart; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.product.variant.ReadableProductVariant; +import com.salesmanager.shop.model.order.total.ReadableOrderTotal; + +/** + * Compatible with v1 + v2 + * @author c.samson + * + */ +public class ReadableShoppingCart extends ShoppingCartEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String code; + private BigDecimal subtotal; + + + private String displaySubTotal; + private BigDecimal total; + private String displayTotal; + private int quantity; + private Long order; + private String promoCode; + + private ReadableProductVariant variant; + + List products = new ArrayList(); + List totals; + + private Long customer; + + + + public Long getCustomer() { + return customer; + } + + + + public void setCustomer(Long customer) { + this.customer = customer; + } + + + + public List getTotals() { + return totals; + } + + + + public void setTotals(List totals) { + this.totals = totals; + } + + + + public List getProducts() { + return products; + } + + + + public void setProducts(List products) { + this.products = products; + } + + + + public String getCode() { + return code; + } + + + + public void setCode(String code) { + this.code = code; + } + + public BigDecimal getSubtotal() { + return subtotal; + } + + + + public void setSubtotal(BigDecimal subtotal) { + this.subtotal = subtotal; + } + + + + public String getDisplaySubTotal() { + return displaySubTotal; + } + + + + public void setDisplaySubTotal(String displaySubTotal) { + this.displaySubTotal = displaySubTotal; + } + + + + public BigDecimal getTotal() { + return total; + } + + + + public void setTotal(BigDecimal total) { + this.total = total; + } + + + + public String getDisplayTotal() { + return displayTotal; + } + + + + public void setDisplayTotal(String displayTotal) { + this.displayTotal = displayTotal; + } + + + + public int getQuantity() { + return quantity; + } + + + + public void setQuantity(int quantity) { + this.quantity = quantity; + } + + + + public Long getOrder() { + return order; + } + + + + public void setOrder(Long order) { + this.order = order; + } + + + + public String getPromoCode() { + return promoCode; + } + + + + public void setPromoCode(String promoCode) { + this.promoCode = promoCode; + } + + + + public ReadableProductVariant getVariant() { + return variant; + } + + + + public void setVariant(ReadableProductVariant variant) { + this.variant = variant; + } + + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ReadableShoppingCartAttribute.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ReadableShoppingCartAttribute.java new file mode 100755 index 0000000000..f62e46277c --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ReadableShoppingCartAttribute.java @@ -0,0 +1,27 @@ +package com.salesmanager.shop.model.shoppingcart; + +import com.salesmanager.shop.model.entity.ShopEntity; + +public class ReadableShoppingCartAttribute extends ShopEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private ReadableShoppingCartAttributeOption option; + private ReadableShoppingCartAttributeOptionValue optionValue; + + public ReadableShoppingCartAttributeOption getOption() { + return option; + } + public void setOption(ReadableShoppingCartAttributeOption option) { + this.option = option; + } + public ReadableShoppingCartAttributeOptionValue getOptionValue() { + return optionValue; + } + public void setOptionValue(ReadableShoppingCartAttributeOptionValue optionValue) { + this.optionValue = optionValue; + } +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ReadableShoppingCartAttributeOption.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ReadableShoppingCartAttributeOption.java new file mode 100755 index 0000000000..40226bb988 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ReadableShoppingCartAttributeOption.java @@ -0,0 +1,12 @@ +package com.salesmanager.shop.model.shoppingcart; + +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductOption; + +public class ReadableShoppingCartAttributeOption extends ReadableProductOption { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ReadableShoppingCartAttributeOptionValue.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ReadableShoppingCartAttributeOptionValue.java new file mode 100755 index 0000000000..aa5417dee3 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ReadableShoppingCartAttributeOptionValue.java @@ -0,0 +1,19 @@ +package com.salesmanager.shop.model.shoppingcart; + +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductOptionValue; + +public class ReadableShoppingCartAttributeOptionValue extends ReadableProductOptionValue { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String name; + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ReadableShoppingCartItem.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ReadableShoppingCartItem.java new file mode 100755 index 0000000000..2e4b508d9a --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ReadableShoppingCartItem.java @@ -0,0 +1,65 @@ +package com.salesmanager.shop.model.shoppingcart; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.shop.model.catalog.product.ReadableMinimalProduct; +import com.salesmanager.shop.model.catalog.product.variation.ReadableProductVariation; + +/** + * compatible with v1 version + * @author c.samson + * + */ +public class ReadableShoppingCartItem extends ReadableMinimalProduct implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private BigDecimal subTotal; + private String displaySubTotal; + private List cartItemattributes = new ArrayList(); + + private ReadableProductVariation variant = null; + private ReadableProductVariation variantValue = null; + + + + public BigDecimal getSubTotal() { + return subTotal; + } + public void setSubTotal(BigDecimal subTotal) { + this.subTotal = subTotal; + } + public String getDisplaySubTotal() { + return displaySubTotal; + } + public void setDisplaySubTotal(String displaySubTotal) { + this.displaySubTotal = displaySubTotal; + } + public List getCartItemattributes() { + return cartItemattributes; + } + public void setCartItemattributes(List cartItemattributes) { + this.cartItemattributes = cartItemattributes; + } + public ReadableProductVariation getVariant() { + return variant; + } + public void setVariant(ReadableProductVariation variant) { + this.variant = variant; + } + public ReadableProductVariation getVariantValue() { + return variantValue; + } + public void setVariantValue(ReadableProductVariation variantValue) { + this.variantValue = variantValue; + } + + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ShoppingCartAttribute.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ShoppingCartAttribute.java new file mode 100755 index 0000000000..8f781d669e --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ShoppingCartAttribute.java @@ -0,0 +1,50 @@ +package com.salesmanager.shop.model.shoppingcart; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.ShopEntity; + +public class ShoppingCartAttribute extends ShopEntity implements Serializable { + + + /** + * + */ + private static final long serialVersionUID = 1L; + private long optionId; + private long optionValueId; + private long attributeId; + private String optionName; + private String optionValue; + public long getOptionId() { + return optionId; + } + public void setOptionId(long optionId) { + this.optionId = optionId; + } + public long getOptionValueId() { + return optionValueId; + } + public void setOptionValueId(long optionValueId) { + this.optionValueId = optionValueId; + } + public String getOptionName() { + return optionName; + } + public void setOptionName(String optionName) { + this.optionName = optionName; + } + public String getOptionValue() { + return optionValue; + } + public void setOptionValue(String optionValue) { + this.optionValue = optionValue; + } + public long getAttributeId() { + return attributeId; + } + public void setAttributeId(long attributeId) { + this.attributeId = attributeId; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ShoppingCartData.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ShoppingCartData.java new file mode 100755 index 0000000000..33634f02f5 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ShoppingCartData.java @@ -0,0 +1,90 @@ +package com.salesmanager.shop.model.shoppingcart; + +import java.io.Serializable; +import java.util.List; + +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import com.salesmanager.shop.model.entity.ShopEntity; +import com.salesmanager.shop.model.order.total.OrderTotal; + + +@Component +@Scope(value = "prototype") +public class ShoppingCartData extends ShopEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String message; + private String code; + private int quantity; + private String total; + private String subTotal; + private Long orderId; + + private List totals;//calculated from OrderTotalSummary + private List shoppingCartItems; + private List unavailables; + + + public String getMessage() { + return message; + } + public void setMessage(String message) { + this.message = message; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public int getQuantity() { + return quantity; + } + public void setQuantity(int quantity) { + this.quantity = quantity; + } + public String getTotal() { + return total; + } + public void setTotal(String total) { + this.total = total; + } + public List getShoppingCartItems() { + return shoppingCartItems; + } + public void setShoppingCartItems(List shoppingCartItems) { + this.shoppingCartItems = shoppingCartItems; + } + public String getSubTotal() { + return subTotal; + } + public void setSubTotal(String subTotal) { + this.subTotal = subTotal; + } + public List getTotals() { + return totals; + } + public void setTotals(List totals) { + this.totals = totals; + } + public List getUnavailables() { + return unavailables; + } + public void setUnavailables(List unavailables) { + this.unavailables = unavailables; + } + public Long getOrderId() { + return orderId; + } + public void setOrderId(Long orderId) { + this.orderId = orderId; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ShoppingCartEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ShoppingCartEntity.java new file mode 100755 index 0000000000..c388c72d90 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ShoppingCartEntity.java @@ -0,0 +1,14 @@ +package com.salesmanager.shop.model.shoppingcart; + +import com.salesmanager.shop.model.entity.ShopEntity; + +public class ShoppingCartEntity extends ShopEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ShoppingCartItem.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ShoppingCartItem.java new file mode 100755 index 0000000000..d77a72a186 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/shoppingcart/ShoppingCartItem.java @@ -0,0 +1,96 @@ +package com.salesmanager.shop.model.shoppingcart; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + +import com.salesmanager.shop.model.entity.ShopEntity; + + +public class ShoppingCartItem extends ShopEntity implements Serializable { + + public String getSku() { + return sku; + } + public void setSku(String sku) { + this.sku = sku; + } + /** + * + */ + private static final long serialVersionUID = 1L; + private String name; + private String price; + private String image; + private BigDecimal productPrice; + private int quantity; + private String sku;//sku + private String code;//shopping cart code + private boolean productVirtual; + + private String subTotal; + + private List shoppingCartAttributes; + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getPrice() { + return price; + } + public void setPrice(String price) { + this.price = price; + } + public int getQuantity() { + if(quantity <= 0) { + quantity = 1; + } + return quantity; + } + public void setQuantity(int quantity) { + this.quantity = quantity; + } + + + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public List getShoppingCartAttributes() { + return shoppingCartAttributes; + } + public void setShoppingCartAttributes(List shoppingCartAttributes) { + this.shoppingCartAttributes = shoppingCartAttributes; + } + public void setProductPrice(BigDecimal productPrice) { + this.productPrice = productPrice; + } + public BigDecimal getProductPrice() { + return productPrice; + } + public void setImage(String image) { + this.image = image; + } + public String getImage() { + return image; + } + public void setSubTotal(String subTotal) { + this.subTotal = subTotal; + } + public String getSubTotal() { + return subTotal; + } + public boolean isProductVirtual() { + return productVirtual; + } + public void setProductVirtual(boolean productVirtual) { + this.productVirtual = productVirtual; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/MerchantConfigEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/MerchantConfigEntity.java new file mode 100755 index 0000000000..a0c6a567a3 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/MerchantConfigEntity.java @@ -0,0 +1,41 @@ +package com.salesmanager.shop.model.store; + +import com.salesmanager.core.model.system.MerchantConfigurationType; +import com.salesmanager.shop.model.entity.Entity; + +public class MerchantConfigEntity extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String key; + private MerchantConfigurationType type; + private String value; + private boolean active; + public String getKey() { + return key; + } + public void setKey(String key) { + this.key = key; + } + public MerchantConfigurationType getType() { + return type; + } + public void setType(MerchantConfigurationType type) { + this.type = type; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + public boolean isActive() { + return active; + } + public void setActive(boolean active) { + this.active = active; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/MerchantStoreBrand.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/MerchantStoreBrand.java new file mode 100755 index 0000000000..a0daeca1ac --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/MerchantStoreBrand.java @@ -0,0 +1,18 @@ +package com.salesmanager.shop.model.store; + +import java.util.ArrayList; +import java.util.List; + +public class MerchantStoreBrand { + + + private List socialNetworks = new ArrayList(); + + public List getSocialNetworks() { + return socialNetworks; + } + public void setSocialNetworks(List socialNetworks) { + this.socialNetworks = socialNetworks; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/MerchantStoreEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/MerchantStoreEntity.java new file mode 100755 index 0000000000..4ca362375b --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/MerchantStoreEntity.java @@ -0,0 +1,152 @@ +package com.salesmanager.shop.model.store; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +import com.salesmanager.shop.model.references.MeasureUnit; +import com.salesmanager.shop.model.references.WeightUnit; + +public class MerchantStoreEntity implements Serializable { + + + /** + * + */ + private static final long serialVersionUID = 1L; + private int id; + @NotNull + private String code; + @NotNull + private String name; + + private String defaultLanguage;//code + private String currency;//code + private String inBusinessSince; + @NotNull + private String email; + @NotNull + private String phone; + private String template; + + private boolean useCache; + private boolean currencyFormatNational; + private boolean retailer; + private MeasureUnit dimension; + private WeightUnit weight; + + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getDefaultLanguage() { + return defaultLanguage; + } + + public void setDefaultLanguage(String defaultLanguage) { + this.defaultLanguage = defaultLanguage; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + + public String getInBusinessSince() { + return inBusinessSince; + } + + public void setInBusinessSince(String inBusinessSince) { + this.inBusinessSince = inBusinessSince; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getTemplate() { + return template; + } + + public void setTemplate(String template) { + this.template = template; + } + + public boolean isCurrencyFormatNational() { + return currencyFormatNational; + } + + public void setCurrencyFormatNational(boolean currencyFormatNational) { + this.currencyFormatNational = currencyFormatNational; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public boolean isUseCache() { + return useCache; + } + + public void setUseCache(boolean useCache) { + this.useCache = useCache; + } + + public MeasureUnit getDimension() { + return dimension; + } + + public void setDimension(MeasureUnit dimension) { + this.dimension = dimension; + } + + public WeightUnit getWeight() { + return weight; + } + + public void setWeight(WeightUnit weight) { + this.weight = weight; + } + + public boolean isRetailer() { + return retailer; + } + + public void setRetailer(boolean retailer) { + this.retailer = retailer; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/PersistableBrand.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/PersistableBrand.java new file mode 100755 index 0000000000..27bc31e260 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/PersistableBrand.java @@ -0,0 +1,5 @@ +package com.salesmanager.shop.model.store; + +public class PersistableBrand extends MerchantStoreBrand { + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/PersistableMerchantStore.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/PersistableMerchantStore.java new file mode 100644 index 0000000000..1f933c6cb9 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/PersistableMerchantStore.java @@ -0,0 +1,42 @@ +package com.salesmanager.shop.model.store; + +import java.util.List; + +import com.salesmanager.shop.model.references.PersistableAddress; + +public class PersistableMerchantStore extends MerchantStoreEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private PersistableAddress address; + //code of parent store (can be null if retailer) + private String retailerStore; + private List supportedLanguages; + + public List getSupportedLanguages() { + return supportedLanguages; + } + + public void setSupportedLanguages(List supportedLanguages) { + this.supportedLanguages = supportedLanguages; + } + + public PersistableAddress getAddress() { + return address; + } + + public void setAddress(PersistableAddress address) { + this.address = address; + } + + public String getRetailerStore() { + return retailerStore; + } + + public void setRetailerStore(String retailerStore) { + this.retailerStore = retailerStore; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/ReadableBrand.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/ReadableBrand.java new file mode 100755 index 0000000000..ae68f572d0 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/ReadableBrand.java @@ -0,0 +1,17 @@ +package com.salesmanager.shop.model.store; + +import com.salesmanager.shop.model.content.ReadableImage; + +public class ReadableBrand extends MerchantStoreBrand { + + private ReadableImage logo; + + public ReadableImage getLogo() { + return logo; + } + + public void setLogo(ReadableImage logo) { + this.logo = logo; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/ReadableMerchantStore.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/ReadableMerchantStore.java new file mode 100755 index 0000000000..e8f01e34a0 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/ReadableMerchantStore.java @@ -0,0 +1,77 @@ +package com.salesmanager.shop.model.store; + +import java.io.Serializable; +import java.util.List; + +import com.salesmanager.shop.model.content.ReadableImage; +import com.salesmanager.shop.model.entity.ReadableAudit; +import com.salesmanager.shop.model.entity.ReadableAuditable; +import com.salesmanager.shop.model.references.ReadableAddress; +import com.salesmanager.shop.model.references.ReadableLanguage; + +public class ReadableMerchantStore extends MerchantStoreEntity implements ReadableAuditable, Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String currentUserLanguage; + private ReadableAddress address; + private ReadableImage logo; + private ReadableAudit audit; + private ReadableMerchantStore parent; + + private List supportedLanguages; + + public String getCurrentUserLanguage() { + return currentUserLanguage; + } + + public void setCurrentUserLanguage(String currentUserLanguage) { + this.currentUserLanguage = currentUserLanguage; + } + + public ReadableAddress getAddress() { + return address; + } + + public void setAddress(ReadableAddress address) { + this.address = address; + } + + public ReadableImage getLogo() { + return logo; + } + + public void setLogo(ReadableImage logo) { + this.logo = logo; + } + + public void setReadableAudit(ReadableAudit audit) { + this.audit = audit; + + } + + public ReadableAudit getReadableAudit() { + return this.audit; + } + + public ReadableMerchantStore getParent() { + return parent; + } + + public void setParent(ReadableMerchantStore parent) { + this.parent = parent; + } + + public List getSupportedLanguages() { + return supportedLanguages; + } + + public void setSupportedLanguages(List supportedLanguages) { + this.supportedLanguages = supportedLanguages; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/ReadableMerchantStoreList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/ReadableMerchantStoreList.java new file mode 100755 index 0000000000..440381cc79 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/store/ReadableMerchantStoreList.java @@ -0,0 +1,24 @@ +package com.salesmanager.shop.model.store; + +import java.util.ArrayList; +import java.util.List; +import com.salesmanager.shop.model.entity.ReadableList; + +public class ReadableMerchantStoreList extends ReadableList { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private List data = new ArrayList(); + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/Configs.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/Configs.java new file mode 100755 index 0000000000..505f86f974 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/Configs.java @@ -0,0 +1,115 @@ +package com.salesmanager.shop.model.system; + +public class Configs { + + private String facebook; + private String pinterest; + private String ga; + private String instagram; + + private boolean allowOnlinePurchase; + private boolean displaySearchBox; + private boolean displayContactUs; + private boolean displayShipping; + + private boolean displayCustomerSection =false; + private boolean displayAddToCartOnFeaturedItems = false; + private boolean displayCustomerAgreement = false; + private boolean displayPagesMenu = true; + + public String getFacebook() { + return facebook; + } + + public void setFacebook(String facebook) { + this.facebook = facebook; + } + + public String getPinterest() { + return pinterest; + } + + public void setPinterest(String pinterest) { + this.pinterest = pinterest; + } + + public String getGa() { + return ga; + } + + public void setGa(String ga) { + this.ga = ga; + } + + public String getInstagram() { + return instagram; + } + + public void setInstagram(String instagram) { + this.instagram = instagram; + } + + public boolean isAllowOnlinePurchase() { + return allowOnlinePurchase; + } + + public void setAllowOnlinePurchase(boolean allowOnlinePurchase) { + this.allowOnlinePurchase = allowOnlinePurchase; + } + + public boolean isDisplaySearchBox() { + return displaySearchBox; + } + + public void setDisplaySearchBox(boolean displaySearchBox) { + this.displaySearchBox = displaySearchBox; + } + + public boolean isDisplayContactUs() { + return displayContactUs; + } + + public void setDisplayContactUs(boolean displayContactUs) { + this.displayContactUs = displayContactUs; + } + + public boolean isDisplayShipping() { + return displayShipping; + } + + public void setDisplayShipping(boolean displayShipping) { + this.displayShipping = displayShipping; + } + + public boolean isDisplayCustomerSection() { + return displayCustomerSection; + } + + public void setDisplayCustomerSection(boolean displayCustomerSection) { + this.displayCustomerSection = displayCustomerSection; + } + + public boolean isDisplayAddToCartOnFeaturedItems() { + return displayAddToCartOnFeaturedItems; + } + + public void setDisplayAddToCartOnFeaturedItems(boolean displayAddToCartOnFeaturedItems) { + this.displayAddToCartOnFeaturedItems = displayAddToCartOnFeaturedItems; + } + + public boolean isDisplayCustomerAgreement() { + return displayCustomerAgreement; + } + + public void setDisplayCustomerAgreement(boolean displayCustomerAgreement) { + this.displayCustomerAgreement = displayCustomerAgreement; + } + + public boolean isDisplayPagesMenu() { + return displayPagesMenu; + } + + public void setDisplayPagesMenu(boolean displayPagesMenu) { + this.displayPagesMenu = displayPagesMenu; + } +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/IntegrationModuleConfiguration.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/IntegrationModuleConfiguration.java new file mode 100644 index 0000000000..89360bf95e --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/IntegrationModuleConfiguration.java @@ -0,0 +1,52 @@ +package com.salesmanager.shop.model.system; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class IntegrationModuleConfiguration extends IntegrationModuleEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private boolean defaultSelected; + private Map integrationKeys = new HashMap(); + private Map> integrationOptions = new HashMap>(); + private List requiredKeys = new ArrayList(); + private String configurable = null; + + + public boolean isDefaultSelected() { + return defaultSelected; + } + public void setDefaultSelected(boolean defaultSelected) { + this.defaultSelected = defaultSelected; + } + public Map getIntegrationKeys() { + return integrationKeys; + } + public void setIntegrationKeys(Map integrationKeys) { + this.integrationKeys = integrationKeys; + } + public Map> getIntegrationOptions() { + return integrationOptions; + } + public void setIntegrationOptions(Map> integrationOptions) { + this.integrationOptions = integrationOptions; + } + public List getRequiredKeys() { + return requiredKeys; + } + public void setRequiredKeys(List requiredKeys) { + this.requiredKeys = requiredKeys; + } + public String getConfigurable() { + return configurable; + } + public void setConfigurable(String configurable) { + this.configurable = configurable; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/IntegrationModuleEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/IntegrationModuleEntity.java new file mode 100644 index 0000000000..ffb041fd95 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/IntegrationModuleEntity.java @@ -0,0 +1,31 @@ +package com.salesmanager.shop.model.system; + +import java.io.Serializable; + +public class IntegrationModuleEntity implements Serializable { + + private String code; + private boolean active; + + /** + * + */ + private static final long serialVersionUID = 1L; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/IntegrationModuleSummaryEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/IntegrationModuleSummaryEntity.java new file mode 100644 index 0000000000..90bc85c7fc --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/IntegrationModuleSummaryEntity.java @@ -0,0 +1,50 @@ +package com.salesmanager.shop.model.system; + +import java.util.ArrayList; +import java.util.List; + +public class IntegrationModuleSummaryEntity extends IntegrationModuleEntity { + + + /** + * + */ + private static final long serialVersionUID = 1L; + private boolean configured; + private String image; + private String binaryImage; + private List requiredKeys = new ArrayList(); + private String configurable = null; + + public List getRequiredKeys() { + return requiredKeys; + } + public void setRequiredKeys(List requiredKeys) { + this.requiredKeys = requiredKeys; + } + public String getImage() { + return image; + } + public void setImage(String image) { + this.image = image; + } + public boolean isConfigured() { + return configured; + } + public void setConfigured(boolean configured) { + this.configured = configured; + } + public String getBinaryImage() { + return binaryImage; + } + public void setBinaryImage(String binaryImage) { + this.binaryImage = binaryImage; + } + public String getConfigurable() { + return configurable; + } + public void setConfigurable(String configurable) { + this.configurable = configurable; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/Optin.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/Optin.java new file mode 100755 index 0000000000..d46c90acf1 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/Optin.java @@ -0,0 +1,12 @@ +package com.salesmanager.shop.model.system; + +import com.salesmanager.shop.model.entity.Entity; + +public class Optin extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/OptinEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/OptinEntity.java new file mode 100755 index 0000000000..7de812ed44 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/OptinEntity.java @@ -0,0 +1,57 @@ +package com.salesmanager.shop.model.system; + +import java.util.Date; + +public class OptinEntity extends Optin { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private Date startDate; + private Date endDate; + private String optinType; + private String store; + private String code; + private String description; + + public Date getStartDate() { + return startDate; + } + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + public Date getEndDate() { + return endDate; + } + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + public String getStore() { + return store; + } + public void setStore(String store) { + this.store = store; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + public String getOptinType() { + return optinType; + } + public void setOptinType(String optinType) { + this.optinType = optinType; + } + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/PersistableOptin.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/PersistableOptin.java new file mode 100755 index 0000000000..ddf4490f16 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/PersistableOptin.java @@ -0,0 +1,10 @@ +package com.salesmanager.shop.model.system; + +public class PersistableOptin extends OptinEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/ReadableOptin.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/ReadableOptin.java new file mode 100755 index 0000000000..16fa90b36b --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/system/ReadableOptin.java @@ -0,0 +1,10 @@ +package com.salesmanager.shop.model.system; + +public class ReadableOptin extends OptinEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/PersistableTaxClass.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/PersistableTaxClass.java new file mode 100644 index 0000000000..eb39eff933 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/PersistableTaxClass.java @@ -0,0 +1,10 @@ +package com.salesmanager.shop.model.tax; + +public class PersistableTaxClass extends TaxClassEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/PersistableTaxRate.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/PersistableTaxRate.java new file mode 100644 index 0000000000..0af8cb17f0 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/PersistableTaxRate.java @@ -0,0 +1,57 @@ +package com.salesmanager.shop.model.tax; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +public class PersistableTaxRate extends TaxRateEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private BigDecimal rate; + private String store; + private String zone; + private String country; + private String taxClass; + private List descriptions = new ArrayList(); + + public BigDecimal getRate() { + return rate; + } + public void setRate(BigDecimal rate) { + this.rate = rate; + } + public String getStore() { + return store; + } + public void setStore(String store) { + this.store = store; + } + public String getZone() { + return zone; + } + public void setZone(String zone) { + this.zone = zone; + } + public String getCountry() { + return country; + } + public void setCountry(String country) { + this.country = country; + } + public List getDescriptions() { + return descriptions; + } + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + public String getTaxClass() { + return taxClass; + } + public void setTaxClass(String taxClass) { + this.taxClass = taxClass; + } +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/ReadableTaxClass.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/ReadableTaxClass.java new file mode 100644 index 0000000000..1ca067cec8 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/ReadableTaxClass.java @@ -0,0 +1,10 @@ +package com.salesmanager.shop.model.tax; + +public class ReadableTaxClass extends TaxClassEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/ReadableTaxRate.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/ReadableTaxRate.java new file mode 100644 index 0000000000..198dac8d71 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/ReadableTaxRate.java @@ -0,0 +1,55 @@ +package com.salesmanager.shop.model.tax; + +public class ReadableTaxRate extends TaxRateEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String rate; + private String store; + private String zone; + private String country; + private ReadableTaxRateDescription description; + private ReadableTaxClass taxClass; + + public ReadableTaxClass getTaxClass() { + return taxClass; + } + public void setTaxClass(ReadableTaxClass taxClass) { + this.taxClass = taxClass; + } + public ReadableTaxRateDescription getDescription() { + return description; + } + public void setDescription(ReadableTaxRateDescription description) { + this.description = description; + } + + public String getRate() { + return rate; + } + public void setRate(String rate) { + this.rate = rate; + } + public String getStore() { + return store; + } + public void setStore(String store) { + this.store = store; + } + public String getZone() { + return zone; + } + public void setZone(String zone) { + this.zone = zone; + } + public String getCountry() { + return country; + } + public void setCountry(String country) { + this.country = country; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/ReadableTaxRateDescription.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/ReadableTaxRateDescription.java new file mode 100644 index 0000000000..9032902bea --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/ReadableTaxRateDescription.java @@ -0,0 +1,12 @@ +package com.salesmanager.shop.model.tax; + +import com.salesmanager.shop.model.catalog.NamedEntity; + +public class ReadableTaxRateDescription extends NamedEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/ReadableTaxRateFull.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/ReadableTaxRateFull.java new file mode 100644 index 0000000000..e3ae1cd862 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/ReadableTaxRateFull.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.model.tax; + +import java.util.ArrayList; +import java.util.List; + +public class ReadableTaxRateFull extends TaxRateEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + List descriptions = new ArrayList(); + public List getDescriptions() { + return descriptions; + } + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/TaxClassEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/TaxClassEntity.java new file mode 100644 index 0000000000..8348d0f0f1 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/TaxClassEntity.java @@ -0,0 +1,36 @@ +package com.salesmanager.shop.model.tax; + +import javax.validation.constraints.Size; + +import com.salesmanager.shop.model.entity.Entity; + +public class TaxClassEntity extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + @Size(min = 1, max = 10) + private String code; + private String name; + private String store; + public String getStore() { + return store; + } + public void setStore(String store) { + this.store = store; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/TaxRateDescription.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/TaxRateDescription.java new file mode 100644 index 0000000000..af913dc659 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/TaxRateDescription.java @@ -0,0 +1,12 @@ +package com.salesmanager.shop.model.tax; + +import com.salesmanager.shop.model.catalog.NamedEntity; + +public class TaxRateDescription extends NamedEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/TaxRateEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/TaxRateEntity.java new file mode 100644 index 0000000000..a023915569 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/tax/TaxRateEntity.java @@ -0,0 +1,26 @@ +package com.salesmanager.shop.model.tax; + +import com.salesmanager.shop.model.entity.Entity; + +public class TaxRateEntity extends Entity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private int priority; + private String code; + public int getPriority() { + return priority; + } + public void setPriority(int priority) { + this.priority = priority; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/PersistableUser.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/PersistableUser.java new file mode 100755 index 0000000000..8a0648834c --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/PersistableUser.java @@ -0,0 +1,70 @@ +package com.salesmanager.shop.model.user; + +import java.util.ArrayList; +import java.util.List; +import com.salesmanager.shop.model.security.PersistableGroup; + +public class PersistableUser extends UserEntity { + + private String password; + private String repeatPassword; + private String store; + private String userName; + private boolean active; + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + /** + * + */ + private static final long serialVersionUID = 1L; + + private List groups = new ArrayList(); + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public List getGroups() { + return groups; + } + + public void setGroups(List groups) { + this.groups = groups; + } + + public String getStore() { + return store; + } + + public void setStore(String store) { + this.store = store; + } + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + + public String getRepeatPassword() { + return repeatPassword; + } + + public void setRepeatPassword(String repeatPassword) { + this.repeatPassword = repeatPassword; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/ReadableUser.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/ReadableUser.java new file mode 100755 index 0000000000..5781967bea --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/ReadableUser.java @@ -0,0 +1,79 @@ +package com.salesmanager.shop.model.user; + +import java.util.ArrayList; +import java.util.List; +import com.salesmanager.shop.model.security.ReadableGroup; +import com.salesmanager.shop.model.security.ReadablePermission; + +public class ReadableUser extends UserEntity { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String lastAccess; + private String loginTime; + private String merchant; + private String userName; + private boolean active; + + private List permissions = new ArrayList(); + private List groups = new ArrayList(); + + public List getGroups() { + return groups; + } + + public void setGroups(List groups) { + this.groups = groups; + } + + public String getLastAccess() { + return lastAccess; + } + + public void setLastAccess(String lastAccess) { + this.lastAccess = lastAccess; + } + + public String getLoginTime() { + return loginTime; + } + + public void setLoginTime(String loginTime) { + this.loginTime = loginTime; + } + + public String getMerchant() { + return merchant; + } + + public void setMerchant(String merchant) { + this.merchant = merchant; + } + + public List getPermissions() { + return permissions; + } + + public void setPermissions(List permissions) { + this.permissions = permissions; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/ReadableUserList.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/ReadableUserList.java new file mode 100755 index 0000000000..210d12e538 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/ReadableUserList.java @@ -0,0 +1,24 @@ +package com.salesmanager.shop.model.user; + +import java.util.ArrayList; +import java.util.List; +import com.salesmanager.shop.model.entity.ReadableList; + +public class ReadableUserList extends ReadableList { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private List data = new ArrayList(); + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/User.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/User.java new file mode 100755 index 0000000000..b51d782279 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/User.java @@ -0,0 +1,19 @@ +package com.salesmanager.shop.model.user; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.Entity; + +/** + * Admin users + * @author carlsamson + * + */ +public class User extends Entity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/UserEntity.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/UserEntity.java new file mode 100755 index 0000000000..7c3db30224 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/UserEntity.java @@ -0,0 +1,69 @@ +package com.salesmanager.shop.model.user; + +public class UserEntity extends User { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String firstName; + private String lastName; + private String emailAddress; + private String defaultLanguage; + private String userName; + private boolean active; + + + + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmailAddress() { + return emailAddress; + } + + public void setEmailAddress(String emailAddress) { + this.emailAddress = emailAddress; + } + + + public String getDefaultLanguage() { + return defaultLanguage; + } + + public void setDefaultLanguage(String defaultLanguage) { + this.defaultLanguage = defaultLanguage; + } + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + +public String getUserName() { + return userName; +} + +public void setUserName(String userName) { + this.userName = userName; +} + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/UserPassword.java b/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/UserPassword.java new file mode 100755 index 0000000000..4b232ff8f7 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/model/user/UserPassword.java @@ -0,0 +1,32 @@ +package com.salesmanager.shop.model.user; + +import java.io.Serializable; + +/** + * Object containing password information + * for change password request + * @author carlsamson + * + */ +public class UserPassword implements Serializable{ + + /** + * + */ + private static final long serialVersionUID = 1L; + String password = null; + String changePassword = null; + public String getPassword() { + return password; + } + public void setPassword(String password) { + this.password = password; + } + public String getChangePassword() { + return changePassword; + } + public void setChangePassword(String changePassword) { + this.changePassword = changePassword; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/catalog/facade/CatalogFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/catalog/facade/CatalogFacade.java new file mode 100644 index 0000000000..f34a982e5d --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/catalog/facade/CatalogFacade.java @@ -0,0 +1,37 @@ +package com.salesmanager.shop.store.controller.catalog.facade; + +import com.salesmanager.core.model.catalog.catalog.Catalog; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.catalog.*; +import com.salesmanager.shop.model.entity.ReadableEntityList; + +import java.util.Optional; + +public interface CatalogFacade { + + ReadableCatalog saveCatalog(PersistableCatalog catalog, MerchantStore store, Language language); + + void updateCatalog(Long catalogId, PersistableCatalog catalog, MerchantStore store, Language language); + + void deleteCatalog(Long catalogId, MerchantStore store, Language language); + + boolean uniqueCatalog(String code, MerchantStore store); + + ReadableCatalog getCatalog(String code, MerchantStore store, Language language); + + Catalog getCatalog(String code, MerchantStore store); + + ReadableCatalog getCatalog(Long id, MerchantStore store, Language language); + + ReadableEntityList getListCatalogs(Optional code, MerchantStore store, Language language, int page, int count); + + ReadableEntityList listCatalogEntry(Optional product, Long catalogId, MerchantStore store, Language language, int page, int count); + + ReadableCatalogCategoryEntry getCatalogEntry(Long id, MerchantStore store, Language language); + + ReadableCatalogCategoryEntry addCatalogEntry(PersistableCatalogCategoryEntry entry, MerchantStore store, Language language); + + void removeCatalogEntry(Long catalogId, Long catalogEntryId, MerchantStore store, Language language); + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/category/facade/CategoryFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/category/facade/CategoryFacade.java new file mode 100755 index 0000000000..86693ab7fb --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/category/facade/CategoryFacade.java @@ -0,0 +1,113 @@ +package com.salesmanager.shop.store.controller.category.facade; + +import java.util.List; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.category.PersistableCategory; +import com.salesmanager.shop.model.catalog.category.ReadableCategory; +import com.salesmanager.shop.model.catalog.category.ReadableCategoryList; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductVariant; +import com.salesmanager.shop.model.entity.ListCriteria; + +public interface CategoryFacade { + + + /** + * Returns a list of ReadableCategory ordered and built according to a given depth + * @param store + * @param depth + * @param language + * @param filter + * @param page + * @param count + * @return ReadableCategoryList + */ + ReadableCategoryList getCategoryHierarchy(MerchantStore store, ListCriteria criteria, int depth, Language language, List filter, int page, int count); + + /** + * + * @param store + * @param category + * @return PersistableCategory + */ + PersistableCategory saveCategory(MerchantStore store, PersistableCategory category); + + /** + * + * @param store + * @param id + * @param language + * @return ReadableCategory + */ + ReadableCategory getById(MerchantStore store, Long id, Language language); + + /** + * + * @param store + * @param code + * @param language + * @return ReadableCategory + * @throws Exception + */ + ReadableCategory getByCode(MerchantStore store, String code, Language language) throws Exception; + + /** + * Get a Category by the Search Engine friendly URL slug + * + * @param merchantStore + * @param friendlyUrl + * @param language + * @return + */ + ReadableCategory getCategoryByFriendlyUrl(MerchantStore merchantStore, String friendlyUrl, Language language) throws Exception; + + Category getByCode(String code, MerchantStore store); + + void deleteCategory(Long categoryId, MerchantStore store); + + void deleteCategory(Category category); + + + /** + * List product options variations for a given category + * @param categoryId + * @param store + * @param language + * @return + */ + List categoryProductVariants(Long categoryId, MerchantStore store, Language language); + + /** + * Check if category code already exist + * @param store + * @param code + * @return + * @throws Exception + */ + boolean existByCode(MerchantStore store, String code); + + /** + * Move a Category from a node to another node + * @param child + * @param parent + * @param store + */ + void move(Long child, Long parent, MerchantStore store); + + /** + * Set category visible or not + * @param category + * @param store + */ + void setVisible(PersistableCategory category, MerchantStore store); + + + /** + * List category by product + * @param store + * @param product + * @return + */ + ReadableCategoryList listByProduct(MerchantStore store, Long product, Language language); +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/configurations/ConfigurationsFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/configurations/ConfigurationsFacade.java new file mode 100644 index 0000000000..024a2d1078 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/configurations/ConfigurationsFacade.java @@ -0,0 +1,19 @@ +package com.salesmanager.shop.store.controller.configurations; + +import java.util.List; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.shop.model.configuration.PersistableConfiguration; +import com.salesmanager.shop.model.configuration.ReadableConfiguration; + +public interface ConfigurationsFacade { + + List configurations(MerchantStore store); + + ReadableConfiguration configuration(String module, MerchantStore store); + + void saveConfiguration(PersistableConfiguration configuration, MerchantStore store); + + void deleteConfiguration(String module, MerchantStore store); + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/content/facade/ContentFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/content/facade/ContentFacade.java new file mode 100755 index 0000000000..190c7591e6 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/content/facade/ContentFacade.java @@ -0,0 +1,183 @@ +package com.salesmanager.shop.store.controller.content.facade; + +import java.util.List; +import java.util.Optional; + +import com.salesmanager.core.model.content.ContentType; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.OutputContentFile; + +//TODO above deprecation, use shop model instead of core model + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.content.ContentFile; +import com.salesmanager.shop.model.content.ContentFolder; +import com.salesmanager.shop.model.content.box.PersistableContentBox; +import com.salesmanager.shop.model.content.box.ReadableContentBox; +import com.salesmanager.shop.model.entity.ReadableEntityList; +import com.salesmanager.shop.model.content.ReadableContentEntity; +import com.salesmanager.shop.model.content.ReadableContentFull; +import com.salesmanager.shop.model.content.page.PersistableContentPage; +import com.salesmanager.shop.model.content.page.ReadableContentPage; + +/** + * Images and files management + * @author carlsamson + * + */ +public interface ContentFacade { + + + ContentFolder getContentFolder(String folder, MerchantStore store) throws Exception; + + /** + * File pth + * @param store + * @param file + * @return + */ + String absolutePath(MerchantStore store, String file); + + /** + * Deletes a file from CMS + * @param store + * @param fileName + */ + void delete(MerchantStore store, String fileName, String fileType); + + /** + * Delete content page + * @param store + * @param id + */ + void delete(MerchantStore store, Long id); + + + + /** + * Returns page names and urls configured for a given MerchantStore + * @param store + * @param language + * @return + * @throws Exception + */ + ReadableEntityList getContentPages(MerchantStore store, Language language, int page, int count); + + + /** + * Returns page name by code + * @param code + * @param store + * @param language + * @return + * @throws Exception + */ + ReadableContentPage getContentPage(String code, MerchantStore store, Language language); + + /** + * Returns page by name + * @param name + * @param store + * @param language + * @return + * @throws Exception + */ + ReadableContentPage getContentPageByName(String name, MerchantStore store, Language language); + + + /** + * Returns a content box for a given code and merchant store + * @param code + * @param store + * @param language + * @return + * @throws Exception + */ + ReadableContentBox getContentBox(String code, MerchantStore store, Language language); + + + /** + * @param code + * @param type + * @param store + * @return + */ + boolean codeExist(String code, String type, MerchantStore store); + + + /** + * Returns content boxes created with code prefix + * for example return boxes with code starting with _ + * @param store + * @param language + * @return + * @throws Exception + */ + ReadableEntityList getContentBoxes(ContentType type, String codePrefix, MerchantStore store, Language language, int start, int count); + + ReadableEntityList getContentBoxes(ContentType type, MerchantStore store, Language language, int start, int count); + + void addContentFile(ContentFile file, String merchantStoreCode); + + /** + * Add multiple files + * @param file + * @param merchantStoreCode + */ + void addContentFiles(List file, String merchantStoreCode); + + /** + * Creates content page + * @param page + * @param merchantStore + * @param language + */ + Long saveContentPage(PersistableContentPage page, MerchantStore merchantStore, Language language); + + void updateContentPage(Long id, PersistableContentPage page, MerchantStore merchantStore, Language language); + + void deleteContent(Long id, MerchantStore merchantStore); + + /** + * Creates content box + * @param box + * @param merchantStore + * @param language + */ + Long saveContentBox(PersistableContentBox box, MerchantStore merchantStore, Language language); + + void updateContentBox(Long id, PersistableContentBox box, MerchantStore merchantStore, Language language); + + + @Deprecated + ReadableContentFull getContent(String code, MerchantStore store, Language language); + + /** + * Get all content types + * @param type + * @param store + * @param language + * @return + */ + List getContents(Optional type, MerchantStore store, Language language); + + /** + * Rename file + * @param store + * @param fileType + * @param originalName + * @param newName + */ + void renameFile(MerchantStore store, FileContentType fileType, String originalName, String newName); + + /** + * Download file + * @param store + * @param fileType + * @param fileName + * @return + */ + OutputContentFile download(MerchantStore store, FileContentType fileType, String fileName); + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/customer/facade/v1/CustomerFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/customer/facade/v1/CustomerFacade.java new file mode 100644 index 0000000000..9bae68008f --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/customer/facade/v1/CustomerFacade.java @@ -0,0 +1,47 @@ +package com.salesmanager.shop.store.controller.customer.facade.v1; + +import java.security.Principal; + +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +public interface CustomerFacade { + + /** validates username with principal **/ + void authorize(Customer customer, Principal principal); + + /** + * + * Forgot password functionality + * @param customerName + * @param store + * @param language + */ + void requestPasswordReset(String customerName, String customerContextPath, MerchantStore store, Language language); + + /** + * Validates if a password request is valid + * @param token + * @param store + */ + void verifyPasswordRequestToken(String token, String store); + + + /** + * Reset password + * @param password + * @param token + * @param store + */ + void resetPassword(String password, String token, String store); + + /** + * Check if customer exist + * @param userName + * @param store + * @return + */ + boolean customerExists(String userName, MerchantStore store); + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/items/facade/ProductItemsFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/items/facade/ProductItemsFacade.java new file mode 100755 index 0000000000..41bd91078a --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/items/facade/ProductItemsFacade.java @@ -0,0 +1,81 @@ +package com.salesmanager.shop.store.controller.items.facade; + +import java.util.List; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.ReadableProductList; +import com.salesmanager.shop.model.catalog.product.group.ProductGroup; + +public interface ProductItemsFacade { + + /** + * List items attached to a Manufacturer + * @param store + * @param language + * @return + */ + ReadableProductList listItemsByManufacturer(MerchantStore store, Language language, Long manufacturerId, int startCount, int maxCount) throws Exception; + + ProductGroup createProductGroup(ProductGroup group, MerchantStore store); + + List listProductGroups(MerchantStore store, Language language); + + /** + * Update product group visible flag + * @param code + * @param group + * @param store + */ + void updateProductGroup(String code, ProductGroup group, MerchantStore store); + + /** + * List product items by id + * @param store + * @param language + * @param ids + * @param startCount + * @param maxCount + * @return + * @throws Exception + */ + ReadableProductList listItemsByIds(MerchantStore store, Language language, List ids, int startCount, int maxCount) throws Exception; + + + /** + * List products created in a group, for instance FEATURED group + * @param group + * @param store + * @param language + * @return + * @throws Exception + */ + ReadableProductList listItemsByGroup(String group, MerchantStore store, Language language) throws Exception; + + /** + * Add product to a group + * @param product + * @param group + * @param store + * @param language + * @return + * @throws Exception + */ + ReadableProductList addItemToGroup(Product product, String group, MerchantStore store, Language language) ; + + /** + * Removes a product from a group + * @param product + * @param group + * @param store + * @param language + * @return + * @throws Exception + */ + ReadableProductList removeItemFromGroup(Product product, String group, MerchantStore store, Language language) throws Exception; + + void deleteGroup(String group, MerchantStore store); + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/manufacturer/facade/ManufacturerFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/manufacturer/facade/ManufacturerFacade.java new file mode 100755 index 0000000000..b60c47d863 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/manufacturer/facade/ManufacturerFacade.java @@ -0,0 +1,84 @@ +package com.salesmanager.shop.store.controller.manufacturer.facade; + +import java.util.List; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.manufacturer.PersistableManufacturer; +import com.salesmanager.shop.model.catalog.manufacturer.ReadableManufacturer; +import com.salesmanager.shop.model.catalog.manufacturer.ReadableManufacturerList; +import com.salesmanager.shop.model.entity.ListCriteria; + +/** + * Manufacturer / brand / collection product grouping + * @author carlsamson + * + */ +public interface ManufacturerFacade { + + List getByProductInCategory(MerchantStore store, Language language, Long categoryId); + + /** + * Creates or saves a manufacturer + * + * @param manufacturer + * @param store + * @param language + * @throws Exception + */ + void saveOrUpdateManufacturer(PersistableManufacturer manufacturer, MerchantStore store, + Language language) throws Exception; + + /** + * Deletes a manufacturer + * + * @param manufacturer + * @param store + * @param language + * @throws Exception + */ + void deleteManufacturer(Manufacturer manufacturer, MerchantStore store, Language language) + throws Exception; + + /** + * Get a Manufacturer by id + * + * @param id + * @param store + * @param language + * @return + * @throws Exception + */ + ReadableManufacturer getManufacturer(Long id, MerchantStore store, Language language) + throws Exception; + + /** + * Get all Manufacturer + * + * @param store + * @param language + * @return + * @throws Exception + */ + ReadableManufacturerList getAllManufacturers(MerchantStore store, Language language, ListCriteria criteria, int page, int count) ; + + /** + * List manufacturers by a specific store + * @param store + * @param language + * @param criteria + * @param page + * @param count + * @return + */ + ReadableManufacturerList listByStore(MerchantStore store, Language language, ListCriteria criteria, int page, int count) ; + + /** + * Determines if manufacturer code already exists + * @param store + * @param manufacturerCode + * @return + */ + boolean manufacturerExist(MerchantStore store, String manufacturerCode); + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/order/facade/v1/OrderFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/order/facade/v1/OrderFacade.java new file mode 100644 index 0000000000..b0d6c97010 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/order/facade/v1/OrderFacade.java @@ -0,0 +1,13 @@ +package com.salesmanager.shop.store.controller.order.facade.v1; + +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.order.v1.ReadableOrderConfirmation; + +public interface OrderFacade { + + ReadableOrderConfirmation orderConfirmation(Order order, Customer customer, MerchantStore store, Language language); + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductCommonFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductCommonFacade.java new file mode 100644 index 0000000000..f59138d898 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductCommonFacade.java @@ -0,0 +1,185 @@ +package com.salesmanager.shop.store.controller.product.facade; + +import java.util.List; + +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.review.ProductReview; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.LightPersistableProduct; +import com.salesmanager.shop.model.catalog.product.PersistableProductReview; +import com.salesmanager.shop.model.catalog.product.ProductPriceEntity; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.model.catalog.product.ReadableProductReview; +import com.salesmanager.shop.model.catalog.product.product.PersistableProduct; + +public interface ProductCommonFacade { + + + /** + * Create / Update product + * @param store + * @param product + * @param language + * @return + */ + Long saveProduct(MerchantStore store, PersistableProduct product, + Language language); + + /** + * Update minimal product details + * @param product + * @param merchant + * @param language + */ + void update(Long productId, LightPersistableProduct product, MerchantStore merchant, Language language); + + /** + * Patch inventory by sku + * @param sku + * @param product + * @param merchant + * @param language + */ + void update(String sku, LightPersistableProduct product, MerchantStore merchant, Language language); + + /** + * Get a Product by id and store + * + * @param store + * @param id + * @param language + * @return + * @throws Exception + */ + ReadableProduct getProduct(MerchantStore store, Long id, Language language) throws Exception; + + /** + * + * @param id + * @param store + * @return + */ + Product getProduct(Long id, MerchantStore store); + + /** + * Reads a product by code + * + * @param store + * @param uniqueCode + * @param language + * @return + * @throws Exception + */ + ReadableProduct getProductByCode(MerchantStore store, String uniqueCode, Language language) + throws Exception; + + + /** + * Sets a new price to an existing product + * + * @param product + * @param price + * @param language + * @return + * @throws Exception + */ + ReadableProduct updateProductPrice(ReadableProduct product, ProductPriceEntity price, + Language language) throws Exception; + + /** + * Sets a new price to an existing product + * + * @param product + * @param quantity + * @param language + * @return + * @throws Exception + */ + ReadableProduct updateProductQuantity(ReadableProduct product, int quantity, Language language) + throws Exception; + + /** + * Deletes a product for a given product id + * + * @param product + * @throws Exception + */ + void deleteProduct(Product product) throws Exception; + + /** + * Delete product + * @param id + * @param store + * @throws Exception + */ + void deleteProduct(Long id, MerchantStore store); + + + + /** + * Adds a product to a category + * + * @param category + * @param product + * @return + */ + ReadableProduct addProductToCategory(Category category, Product product, Language language); + + /** + * Removes item from a category + * + * @param category + * @param product + * @param language + * @return + * @throws Exception + */ + ReadableProduct removeProductFromCategory(Category category, Product product, Language language) + throws Exception; + + + /** + * Saves or updates a Product review + * + * @param review + * @param language + * @throws Exception + */ + void saveOrUpdateReview(PersistableProductReview review, MerchantStore store, Language language) + throws Exception; + + /** + * Deletes a product review + * + * @param review + * @param store + * @param language + * @throws Exception + */ + void deleteReview(ProductReview review, MerchantStore store, Language language) throws Exception; + + /** + * Get reviews for a given product + * + * @param product + * @param store + * @param language + * @return + * @throws Exception + */ + List getProductReviews(Product product, MerchantStore store, + Language language) throws Exception; + + /** + * validates if product exists + * @param sku + * @param store + * @return + */ + public boolean exists(String sku, MerchantStore store); + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductDefinitionFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductDefinitionFacade.java new file mode 100644 index 0000000000..f6a7c8e21b --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductDefinitionFacade.java @@ -0,0 +1,46 @@ +package com.salesmanager.shop.store.controller.product.facade; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.product.definition.PersistableProductDefinition; +import com.salesmanager.shop.model.catalog.product.product.definition.ReadableProductDefinition; + +public interface ProductDefinitionFacade { + + /** + * + * @param store + * @param product + * @param language + * @return + */ + Long saveProductDefinition(MerchantStore store, PersistableProductDefinition product, Language language); + + /** + * + * @param productId + * @param product + * @param merchant + * @param language + */ + void update(Long productId, PersistableProductDefinition product, MerchantStore merchant, Language language); + + /** + * + * @param store + * @param id + * @param language + * @return + */ + ReadableProductDefinition getProduct(MerchantStore store, Long id, Language language); + + /** + * + * @param store + * @param uniqueCode + * @param language + * @return + */ + ReadableProductDefinition getProductBySku(MerchantStore store, String uniqueCode, Language language); + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductFacade.java new file mode 100755 index 0000000000..4eeb270c68 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductFacade.java @@ -0,0 +1,85 @@ +package com.salesmanager.shop.store.controller.product.facade; + +import java.util.List; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.ProductCriteria; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.ProductPriceRequest; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.model.catalog.product.ReadableProductList; +import com.salesmanager.shop.model.catalog.product.ReadableProductPrice; + +public interface ProductFacade { + + + + + /** + * + * @param id + * @param store + * @return + */ + Product getProduct(Long id, MerchantStore store); + + /** + * Reads a product by code + * + * @param store + * @param uniqueCode + * @param language + * @return + * @throws Exception + */ + ReadableProduct getProductByCode(MerchantStore store, String uniqueCode, Language language); + + /** + * Get a product by sku and store + * + * @param store + * @param sku + * @param language + * @return + * @throws Exception + */ + ReadableProduct getProduct(MerchantStore store, String sku, Language language) throws Exception; + + /** + * Get a Product by friendlyUrl (slug), store and language + * + * @param store + * @param friendlyUrl + * @param language + * @return + * @throws Exception + */ + ReadableProduct getProductBySeUrl(MerchantStore store, String friendlyUrl, Language language) throws Exception; + + /** + * Filters a list of product based on criteria + * + * @param store + * @param language + * @param criterias + * @return + * @throws Exception + */ + ReadableProductList getProductListsByCriterias(MerchantStore store, Language language, + ProductCriteria criterias) throws Exception; + + /** + * Get related items + * + * @param store + * @param product + * @param language + * @return + * @throws Exception + */ + List relatedItems(MerchantStore store, Product product, Language language) + throws Exception; + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductInventoryFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductInventoryFacade.java new file mode 100644 index 0000000000..21c82a94e4 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductInventoryFacade.java @@ -0,0 +1,25 @@ +package com.salesmanager.shop.store.controller.product.facade; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.inventory.PersistableInventory; +import com.salesmanager.shop.model.catalog.product.inventory.ReadableInventory; +import com.salesmanager.shop.model.entity.ReadableEntityList; + +public interface ProductInventoryFacade { + + ReadableInventory get(Long inventoryId, MerchantStore store, Language language); + + ReadableEntityList get(String sku, MerchantStore store, Language language, int page, int count); + + ReadableInventory add(PersistableInventory inventory, MerchantStore store, Language language); + + void update(PersistableInventory inventory, MerchantStore store, Language language); + + void delete(Long productId, Long inventoryId, MerchantStore store); + + ReadableEntityList get(Long productId, MerchantStore store, Language language, int page, int count); + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductOptionFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductOptionFacade.java new file mode 100644 index 0000000000..c6e9031029 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductOptionFacade.java @@ -0,0 +1,61 @@ +package com.salesmanager.shop.store.controller.product.facade; + +import java.util.List; + +import org.springframework.web.multipart.MultipartFile; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductAttribute; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductOptionValue; +import com.salesmanager.shop.model.catalog.product.attribute.api.PersistableProductOptionEntity; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductAttributeEntity; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductAttributeList; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionEntity; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionList; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionValue; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionValueList; +import com.salesmanager.shop.model.entity.CodeEntity; + + +/* + * Attributes, Options and Options values management independently from Product + */ +public interface ProductOptionFacade { + + ReadableProductOptionEntity getOption(Long optionId, MerchantStore store, Language language); + + ReadableProductOptionValue getOptionValue(Long optionValueId, MerchantStore store, Language language); + + ReadableProductOptionEntity saveOption(PersistableProductOptionEntity option, MerchantStore store, Language language); + + ReadableProductOptionValue saveOptionValue(PersistableProductOptionValue optionValue, MerchantStore store, Language language); + + List createAttributes(List attributes, Long productId, MerchantStore store); + void updateAttributes(List attributes, Long productId, MerchantStore store); + + void addOptionValueImage(MultipartFile image, Long optionValueId, MerchantStore store, Language language); + + void removeOptionValueImage(Long optionValueId, MerchantStore store, Language language); + + boolean optionExists(String code, MerchantStore store); + + boolean optionValueExists(String code, MerchantStore store); + + void deleteOption(Long optionId, MerchantStore store); + + void deleteOptionValue(Long optionValueId, MerchantStore store); + + ReadableProductOptionList options(MerchantStore store, Language language, String name, int page, int count); + + ReadableProductOptionValueList optionValues(MerchantStore store, Language language, String name, int page, int count); + + ReadableProductAttributeEntity saveAttribute(Long productId, PersistableProductAttribute attribute, MerchantStore store, Language language); + + ReadableProductAttributeEntity getAttribute(Long productId, Long attributeId, MerchantStore store, Language language); + + ReadableProductAttributeList getAttributesList(Long productId, MerchantStore store, Language language, int page, int count); + + void deleteAttribute(Long productId, Long attributeId, MerchantStore store); + +} \ No newline at end of file diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductOptionSetFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductOptionSetFacade.java new file mode 100644 index 0000000000..0a3ce3e9c3 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductOptionSetFacade.java @@ -0,0 +1,24 @@ +package com.salesmanager.shop.store.controller.product.facade; + +import java.util.List; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.attribute.optionset.PersistableProductOptionSet; +import com.salesmanager.shop.model.catalog.product.attribute.optionset.ReadableProductOptionSet; + +public interface ProductOptionSetFacade { + + + ReadableProductOptionSet get(Long id, MerchantStore store, Language language); + boolean exists(String code, MerchantStore store); + List list(MerchantStore store, Language language); + List list(MerchantStore store, Language language, String type); + void create(PersistableProductOptionSet optionSet, MerchantStore store, Language language); + void update(Long id, PersistableProductOptionSet optionSet, MerchantStore store, Language language); + void delete(Long id, MerchantStore store); + + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductPriceFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductPriceFacade.java new file mode 100644 index 0000000000..0bceeec93e --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductPriceFacade.java @@ -0,0 +1,77 @@ +package com.salesmanager.shop.store.controller.product.facade; + +import java.util.List; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.PersistableProductPrice; +import com.salesmanager.shop.model.catalog.product.ReadableProductPrice; + + +/** + * Product price management api + * @author carlsamson + * + */ +public interface ProductPriceFacade { + + /** + * Calculate product price based on specific product options + * + * @param id + * @param priceRequest + * @param store + * @param language + * @return + */ + /** + * ReadableProductPrice getProductPrice(Long id, ProductPriceRequest + * priceRequest, MerchantStore store, Language language); + **/ + + /** + * Creates a product price + * @param price + * @param productId + * @param inventoryId + * @param store + * @return + */ + Long save(PersistableProductPrice price, MerchantStore store); + + /** + * Product price deletion + * @param priceId + * @param productId + * @param inventoryId + * @param store + */ + void delete(Long priceId, String sku, MerchantStore store); + + /** + * List product prices by product and inventory (product and variants) + * @param productId + * @param inventoryId + * @param store + * @return + */ + List list(String sku, Long inventoryId, MerchantStore store, Language language); + + /** + * List product prices by product + * @param poductId + * @param store + * @return + */ + List list(String sku, MerchantStore store, Language language); + + /** + * Get ProductPrice + * @param sku + * @param productPriceId + * @param store + * @param language + * @return + */ + ReadableProductPrice get(String sku, Long productPriceId, MerchantStore store, Language language); +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductTypeFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductTypeFacade.java new file mode 100644 index 0000000000..3fbdb8082b --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductTypeFacade.java @@ -0,0 +1,25 @@ +package com.salesmanager.shop.store.controller.product.facade; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.type.PersistableProductType; +import com.salesmanager.shop.model.catalog.product.type.ReadableProductType; +import com.salesmanager.shop.model.catalog.product.type.ReadableProductTypeList; + +public interface ProductTypeFacade { + + ReadableProductTypeList getByMerchant(MerchantStore store, Language language, int count, int page); + + ReadableProductType get(MerchantStore store, Long id, Language language); + + ReadableProductType get(MerchantStore store, String code, Language language); + + Long save(PersistableProductType type, MerchantStore store, Language language); + + void update(PersistableProductType type, Long id, MerchantStore store, Language language); + + void delete(Long id, MerchantStore store, Language language); + + boolean exists(String code, MerchantStore store, Language language); + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductVariantFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductVariantFacade.java new file mode 100644 index 0000000000..bdffad79dd --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductVariantFacade.java @@ -0,0 +1,19 @@ +package com.salesmanager.shop.store.controller.product.facade; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.product.variant.PersistableProductVariant; +import com.salesmanager.shop.model.catalog.product.product.variant.ReadableProductVariant; +import com.salesmanager.shop.model.entity.ReadableEntityList; + +public interface ProductVariantFacade { + + ReadableProductVariant get(Long instanceId, Long productId, MerchantStore store, Language language); + boolean exists(String sku, MerchantStore store, Long productId, Language language); + Long create(PersistableProductVariant productVariant, Long productId, MerchantStore store, Language language); + void update(Long instanceId, PersistableProductVariant instance, Long productId, MerchantStore store, Language language); + void delete(Long productVariant, Long productId, MerchantStore store); + ReadableEntityList list(Long productId, MerchantStore store, Language language, int page, int count); + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductVariantGroupFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductVariantGroupFacade.java new file mode 100644 index 0000000000..a56c65de0d --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductVariantGroupFacade.java @@ -0,0 +1,24 @@ +package com.salesmanager.shop.store.controller.product.facade; + +import org.springframework.web.multipart.MultipartFile; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.product.variantGroup.PersistableProductVariantGroup; +import com.salesmanager.shop.model.catalog.product.product.variantGroup.ReadableProductVariantGroup; +import com.salesmanager.shop.model.entity.ReadableEntityList; + +public interface ProductVariantGroupFacade { + + ReadableProductVariantGroup get(Long instanceGroupId, MerchantStore store, Language language); + Long create(PersistableProductVariantGroup productVariantGroup, MerchantStore store, Language language); + void update(Long productVariantGroup, PersistableProductVariantGroup instance, MerchantStore store, Language language); + void delete(Long productVariant, Long productId, MerchantStore store); + ReadableEntityList list(Long productId, MerchantStore store, Language language, int page, int count); + + void addImage(MultipartFile image, Long instanceGroupId, + MerchantStore store, Language language); + + void removeImage(Long imageId, Long instanceGroupId, MerchantStore store); + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductVariationFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductVariationFacade.java new file mode 100644 index 0000000000..1c5b1a5537 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/product/facade/ProductVariationFacade.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.store.controller.product.facade; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.variation.PersistableProductVariation; +import com.salesmanager.shop.model.catalog.product.variation.ReadableProductVariation; +import com.salesmanager.shop.model.entity.ReadableEntityList; + +public interface ProductVariationFacade { + + + ReadableProductVariation get(Long variationId, MerchantStore store, Language language); + boolean exists(String code, MerchantStore store); + Long create(PersistableProductVariation optionSet, MerchantStore store, Language language); + void update(Long variationId, PersistableProductVariation variation, MerchantStore store, Language language); + void delete(Long variation, MerchantStore store); + ReadableEntityList list(MerchantStore store, Language language, int page, int count); + + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/shipping/facade/ShippingFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/shipping/facade/ShippingFacade.java new file mode 100644 index 0000000000..4d37bbbf35 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/shipping/facade/ShippingFacade.java @@ -0,0 +1,44 @@ +package com.salesmanager.shop.store.controller.shipping.facade; + +import java.util.List; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shipping.PackageDetails; +import com.salesmanager.shop.model.references.PersistableAddress; +import com.salesmanager.shop.model.references.ReadableAddress; +import com.salesmanager.shop.model.references.ReadableCountry; +import com.salesmanager.shop.model.shipping.ExpeditionConfiguration; + +public interface ShippingFacade { + + ExpeditionConfiguration getExpeditionConfiguration(MerchantStore store, Language language); + void saveExpeditionConfiguration(ExpeditionConfiguration expedition, MerchantStore store); + + + ReadableAddress getShippingOrigin(MerchantStore store); + void saveShippingOrigin(PersistableAddress address, MerchantStore store); + + + void createPackage(PackageDetails packaging, MerchantStore store); + + PackageDetails getPackage(String code, MerchantStore store); + + /** + * List of configured ShippingCountry for a given store + * @param store + * @param lanuage + * @return + */ + List shipToCountry(MerchantStore store, Language lanuage); + + List listPackages(MerchantStore store); + + void updatePackage(String code, PackageDetails packaging, MerchantStore store); + + void deletePackage(String code, MerchantStore store); + + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/shipping/facade/ShippingModuleConfigurationFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/shipping/facade/ShippingModuleConfigurationFacade.java new file mode 100644 index 0000000000..3695b5e52a --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/shipping/facade/ShippingModuleConfigurationFacade.java @@ -0,0 +1,5 @@ +package com.salesmanager.shop.store.controller.shipping.facade; + +public interface ShippingModuleConfigurationFacade { + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/shoppingCart/facade/v1/ShoppingCartFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/shoppingCart/facade/v1/ShoppingCartFacade.java new file mode 100644 index 0000000000..9c5c6db39f --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/shoppingCart/facade/v1/ShoppingCartFacade.java @@ -0,0 +1,13 @@ +package com.salesmanager.shop.store.controller.shoppingCart.facade.v1; + +import java.util.Optional; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.shoppingcart.ReadableShoppingCart; + +public interface ShoppingCartFacade { + + ReadableShoppingCart get(Optional cart, Long customerId, MerchantStore store, Language language); + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/tax/facade/TaxFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/tax/facade/TaxFacade.java new file mode 100644 index 0000000000..ccb734e793 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/tax/facade/TaxFacade.java @@ -0,0 +1,37 @@ +package com.salesmanager.shop.store.controller.tax.facade; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.entity.Entity; +import com.salesmanager.shop.model.entity.ReadableEntityList; +import com.salesmanager.shop.model.tax.PersistableTaxClass; +import com.salesmanager.shop.model.tax.PersistableTaxRate; +import com.salesmanager.shop.model.tax.ReadableTaxClass; +import com.salesmanager.shop.model.tax.ReadableTaxRate; + +public interface TaxFacade { + + + //tax class + Entity createTaxClass(PersistableTaxClass taxClass, MerchantStore store, Language language); + void updateTaxClass(Long id, PersistableTaxClass taxClass, MerchantStore store, Language language); + void deleteTaxClass(Long id, MerchantStore store, Language language); + boolean existsTaxClass(String code, MerchantStore store, Language language); + + ReadableEntityList taxClasses(MerchantStore store, Language language); + ReadableTaxClass taxClass(String code, MerchantStore store, Language language); + + + //tax rate + Entity createTaxRate(PersistableTaxRate taxRate, MerchantStore store, Language language); + void updateTaxRate(Long id, PersistableTaxRate taxRate, MerchantStore store, Language language); + void deleteTaxRate(Long id, MerchantStore store, Language language); + boolean existsTaxRate(String code, MerchantStore store, Language language); + + ReadableEntityList taxRates(MerchantStore store, Language language); + ReadableTaxRate taxRate(Long id, MerchantStore store, Language language); + + + + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/user/facade/UserFacade.java b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/user/facade/UserFacade.java new file mode 100755 index 0000000000..f8e2351617 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/store/controller/user/facade/UserFacade.java @@ -0,0 +1,183 @@ +package com.salesmanager.shop.store.controller.user.facade; + +import java.util.List; + +import com.salesmanager.core.model.common.Criteria; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.user.UserCriteria; +import com.salesmanager.shop.model.security.ReadablePermission; +import com.salesmanager.shop.model.user.PersistableUser; +import com.salesmanager.shop.model.user.ReadableUser; +import com.salesmanager.shop.model.user.ReadableUserList; +import com.salesmanager.shop.model.user.UserPassword; + +/** + * Access to all methods for managing users + * + * @author carlsamson + * + */ +public interface UserFacade { + + /** + * Finds a User by userName + * + * @return + * @throws Exception + */ + ReadableUser findByUserName(String userName, String storeCode, Language lang); + + /** + * Find user by userName + * @param userName + * @return + */ + ReadableUser findByUserName(String userName); + + /** + * Find user by id + * @param id + * @param store + * @param lang + * @return + */ + ReadableUser findById(Long id, MerchantStore store, Language lang); + + /** + * Creates a User + * @param user + * @param store + */ + ReadableUser create(PersistableUser user, MerchantStore store); + + /** + * List permissions by group + * + * @param ids + * @return + * @throws Exception + */ + List findPermissionsByGroups(List ids); + + /** + * Determines if a user is authorized to perform an action on a specific store + * + * @param userName + * @param merchantStoreCode + * @return + * @throws Exception + */ + boolean authorizedStore(String userName, String merchantStoreCode); + + + /** + * Method to be used in argument resolver. + * @param store + * @return + */ + boolean authorizeStore(MerchantStore store, String path); + + /** + * Determines if a user is in a specific group + * @param userName + * @param groupNames + */ + void authorizedGroup(String userName, List groupNames); + + /** + * Check if user is in specific list of roles + * @param userName + * @param groupNames + * @return + */ + boolean userInRoles(String userName, List groupNames); + + + /** + * Sends reset password email + * @param user + * @param store + * @param language + */ + void sendResetPasswordEmail(ReadableUser user, MerchantStore store, Language language); + + /** + * Retrieve authenticated user + * @return + */ + String authenticatedUser(); + + /** + * Get by criteria + * @param criteria + * @return + */ + @Deprecated + ReadableUserList getByCriteria(Language language,String draw,Criteria criteria); + + /** + * List users + * @param criteria + * @param page + * @param count + * @param language + * @return + */ + ReadableUserList listByCriteria (UserCriteria criteria, int page, int count, Language language); + + /** + * Delete user + * @param id + */ + void delete(Long id, String storeCode); + + /** + * Update User + * @param user + */ + ReadableUser update(Long id, String authenticatedUser, MerchantStore store, PersistableUser user); + + /** + * Change password request + * @param userId + * @param authenticatedUser + * @param changePassword + */ + void changePassword(Long userId, String authenticatedUser, UserPassword changePassword); + + void authorizedGroups(String authenticatedUser, PersistableUser user); + + /** + * Update user enable / disabled flag + * @param store + * @param user + */ + void updateEnabled(MerchantStore store, PersistableUser user); + + /** + * + * Forgot password functionality + * @param userName + * @param store + * @param language + */ + void requestPasswordReset(String userName, String userContextPath, MerchantStore store, Language language); + + /** + * Validates if a password request is valid + * @param token + * @param store + */ + void verifyPasswordRequestToken(String token, String store); + + + /** + * Reset password + * @param password + * @param token + * @param store + */ + void resetPassword(String password, String token, String store); + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/util/ReadableEntityUtil.java b/sm-shop-model/src/main/java/com/salesmanager/shop/util/ReadableEntityUtil.java new file mode 100644 index 0000000000..0bae0deb80 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/util/ReadableEntityUtil.java @@ -0,0 +1,20 @@ +package com.salesmanager.shop.util; + +import com.salesmanager.shop.model.entity.ReadableEntityList; +import org.springframework.data.domain.Page; + +import java.util.List; + +public final class ReadableEntityUtil { + + private ReadableEntityUtil() {} + + public static ReadableEntityList createReadableList(Page entityList, List items) { + ReadableEntityList readableList = new ReadableEntityList<>(); + readableList.setItems(items); + readableList.setTotalPages(entityList.getTotalPages()); + readableList.setRecordsTotal(entityList.getTotalElements()); + readableList.setNumber(items.size()); + return readableList; + } +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/validation/BeanUtils.java b/sm-shop-model/src/main/java/com/salesmanager/shop/validation/BeanUtils.java new file mode 100755 index 0000000000..717d3daae1 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/validation/BeanUtils.java @@ -0,0 +1,65 @@ +package com.salesmanager.shop.validation; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class BeanUtils +{ + private BeanUtils(){ + + } + + public static BeanUtils newInstance(){ + return new BeanUtils(); + } + + @SuppressWarnings( "nls" ) + public Object getPropertyValue( Object bean, String property ) + throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException + { + + if (bean == null) { + throw new IllegalArgumentException("No bean specified"); + } + if(property == null){ + + throw new IllegalArgumentException("No name specified for bean class '" + bean.getClass() + "'"); + } + Class beanClass = bean.getClass(); + PropertyDescriptor propertyDescriptor = getPropertyDescriptor( beanClass, property ); + if ( propertyDescriptor == null ) + { + throw new IllegalArgumentException( "No such property " + property + " for " + beanClass + " exists" ); + } + + Method readMethod = propertyDescriptor.getReadMethod(); + if ( readMethod == null ) + { + throw new IllegalStateException( "No getter available for property " + property + " on " + beanClass ); + } + return readMethod.invoke( bean ); + } + + private PropertyDescriptor getPropertyDescriptor( Class beanClass, String propertyname ) + throws IntrospectionException + { + BeanInfo beanInfo = Introspector.getBeanInfo( beanClass ); + PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); + PropertyDescriptor propertyDescriptor = null; + for ( int i = 0; i < propertyDescriptors.length; i++ ) + { + PropertyDescriptor currentPropertyDescriptor = propertyDescriptors[i]; + if ( currentPropertyDescriptor.getName().equals( propertyname ) ) + { + propertyDescriptor = currentPropertyDescriptor; + } + + } + return propertyDescriptor; + } + +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/validation/Enum.java b/sm-shop-model/src/main/java/com/salesmanager/shop/validation/Enum.java new file mode 100755 index 0000000000..b99b3b6e74 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/validation/Enum.java @@ -0,0 +1,27 @@ +package com.salesmanager.shop.validation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.validation.Constraint; +import javax.validation.Payload; + +@Documented +@Constraint(validatedBy = {EnumValidator.class}) +@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER }) +@Retention(RetentionPolicy.RUNTIME) +public @interface Enum +{ + public abstract String message() default "Invalid value. This is not permitted."; + + public abstract Class[] groups() default {}; + + public abstract Class[] payload() default {}; + + public abstract Class> enumClass(); + + public abstract boolean ignoreCase() default false; +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/validation/EnumValidator.java b/sm-shop-model/src/main/java/com/salesmanager/shop/validation/EnumValidator.java new file mode 100755 index 0000000000..c7d70d6171 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/validation/EnumValidator.java @@ -0,0 +1,45 @@ +package com.salesmanager.shop.validation; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + + +/** + * Validates values of a String used as payload in REST service + * Solution taken from https://funofprograming.wordpress.com/2016/09/29/java-enum-validator/ + * @author c.samson + * + */ +public class EnumValidator implements ConstraintValidator +{ + private Enum annotation; + + + public void initialize(Enum annotation) + { + this.annotation = annotation; + } + + + public boolean isValid(String valueForValidation, ConstraintValidatorContext constraintValidatorContext) + { + boolean result = false; + + Object[] enumValues = this.annotation.enumClass().getEnumConstants(); + + if(enumValues != null) + { + for(Object enumValue:enumValues) + { + if(valueForValidation.equals(enumValue.toString()) + || (this.annotation.ignoreCase() && valueForValidation.equalsIgnoreCase(enumValue.toString()))) + { + result = true; + break; + } + } + } + + return result; + } +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/validation/FieldMatch.java b/sm-shop-model/src/main/java/com/salesmanager/shop/validation/FieldMatch.java new file mode 100755 index 0000000000..73c076cae2 --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/validation/FieldMatch.java @@ -0,0 +1,70 @@ +/** + * + */ +package com.salesmanager.shop.validation; + +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.validation.Constraint; +import javax.validation.Payload; + + +/** + * + * Validation annotation to validate that 2 fields have the same value. + * An array of fields and their matching confirmation fields can be supplied. + * + * Example, compare 1 pair of fields: + * @FieldMatch(first = "password", second = "confirmPassword", message = "The password fields must match") + * + * Example, compare more than 1 pair of fields: + * @FieldMatch.List({ + * @FieldMatch(first = "password", second = "confirmPassword", message = "The password fields must match"), + * @FieldMatch(first = "email", second = "confirmEmail", message = "The email fields must match")}) + * + * @author Umesh Awasthi + * + */ + +@Constraint(validatedBy = FieldMatchValidator.class) +@Documented +@Target({TYPE, ANNOTATION_TYPE}) +@Retention(RUNTIME) +public @interface FieldMatch +{ + + String message() default "Fields are not matching"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + /** + * @return The first field + */ + String first(); + + /** + * @return The second field + */ + String second(); + + /** + * Defines several @FieldMatch annotations on the same element + * + * @see FieldMatch + */ + @Target({TYPE, ANNOTATION_TYPE}) + @Retention(RUNTIME) + @Documented + @interface List + { + FieldMatch[] value(); + } +} diff --git a/sm-shop-model/src/main/java/com/salesmanager/shop/validation/FieldMatchValidator.java b/sm-shop-model/src/main/java/com/salesmanager/shop/validation/FieldMatchValidator.java new file mode 100755 index 0000000000..d87aa693cc --- /dev/null +++ b/sm-shop-model/src/main/java/com/salesmanager/shop/validation/FieldMatchValidator.java @@ -0,0 +1,41 @@ +package com.salesmanager.shop.validation; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + + +public class FieldMatchValidator implements ConstraintValidator +{ + + private static final Logger LOG=LoggerFactory.getLogger(FieldMatchValidator.class); + private String firstFieldName; + private String secondFieldName; + private BeanUtils beanUtils; + + public void initialize(final FieldMatch constraintAnnotation) + { + this.firstFieldName = constraintAnnotation.first(); + this.secondFieldName = constraintAnnotation.second(); + this.beanUtils = BeanUtils.newInstance(); + } + + @SuppressWarnings( "nls" ) + public boolean isValid(final Object value, final ConstraintValidatorContext context) + { + try + { + final Object firstObj = this.beanUtils.getPropertyValue(value, this.firstFieldName); + final Object secondObj = this.beanUtils.getPropertyValue(value, this.secondFieldName); + return firstObj == null && secondObj == null || firstObj != null && firstObj.equals(secondObj); + } + catch (final Exception ex) + { + LOG.info( "Error while getting values from object", ex ); + return false; + + } + + } +} diff --git a/sm-shop/.dockerignore b/sm-shop/.dockerignore new file mode 100755 index 0000000000..e69de29bb2 diff --git a/sm-shop/.gitignore b/sm-shop/.gitignore new file mode 100755 index 0000000000..b3f4be25ae --- /dev/null +++ b/sm-shop/.gitignore @@ -0,0 +1,2 @@ +/target/ +/src/main/resources/database.properties diff --git a/sm-shop/.mvn/wrapper/MavenWrapperDownloader.java b/sm-shop/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100755 index 0000000000..fa4f7b499f --- /dev/null +++ b/sm-shop/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,110 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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 + + http://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. +*/ + +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = + "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: : " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/sm-shop/.mvn/wrapper/maven-wrapper.properties b/sm-shop/.mvn/wrapper/maven-wrapper.properties new file mode 100755 index 0000000000..a5fcc11920 --- /dev/null +++ b/sm-shop/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip \ No newline at end of file diff --git a/sm-shop/Dockerfile b/sm-shop/Dockerfile new file mode 100644 index 0000000000..540c187a4b --- /dev/null +++ b/sm-shop/Dockerfile @@ -0,0 +1,7 @@ +FROM adoptopenjdk/openjdk11-openj9:alpine +RUN mkdir /opt/app +RUN mkdir /files +COPY target/shopizer.jar /opt/app +COPY SALESMANAGER.h2.db / +COPY ./files /files +CMD ["java", "-jar", "/opt/app/shopizer.jar"] \ No newline at end of file diff --git a/sm-shop/SALESMANAGER.h2.db b/sm-shop/SALESMANAGER.h2.db new file mode 100644 index 0000000000..272b3fd34a Binary files /dev/null and b/sm-shop/SALESMANAGER.h2.db differ diff --git a/sm-shop/SALESMANAGER.trace.db b/sm-shop/SALESMANAGER.trace.db new file mode 100644 index 0000000000..2f7a395ec8 --- /dev/null +++ b/sm-shop/SALESMANAGER.trace.db @@ -0,0 +1,8 @@ +2022-01-11 09:16:53 jdbc[4]: exception +org.h2.jdbc.JdbcSQLNonTransientException: The object is already closed [90007-200] +2022-01-11 09:16:53 jdbc[4]: exception +org.h2.jdbc.JdbcSQLNonTransientException: The object is already closed [90007-200] +2022-01-11 13:57:02 jdbc[5]: exception +org.h2.jdbc.JdbcSQLNonTransientException: The object is already closed [90007-200] +2022-01-11 13:57:02 jdbc[5]: exception +org.h2.jdbc.JdbcSQLNonTransientException: The object is already closed [90007-200] diff --git a/sm-shop/files/repos/FilesRepository.dat b/sm-shop/files/repos/FilesRepository.dat new file mode 100644 index 0000000000..0ad026baf9 Binary files /dev/null and b/sm-shop/files/repos/FilesRepository.dat differ diff --git a/sm-shop/files/store/DownlaodRepository.dat b/sm-shop/files/store/DownlaodRepository.dat new file mode 100644 index 0000000000..964909ad38 Binary files /dev/null and b/sm-shop/files/store/DownlaodRepository.dat differ diff --git a/sm-shop/files/store/StoreRepository.dat b/sm-shop/files/store/StoreRepository.dat new file mode 100644 index 0000000000..0ad026baf9 Binary files /dev/null and b/sm-shop/files/store/StoreRepository.dat differ diff --git a/sm-shop/mvnw b/sm-shop/mvnw new file mode 100755 index 0000000000..5551fde8e7 --- /dev/null +++ b/sm-shop/mvnw @@ -0,0 +1,286 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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 +# +# http://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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + wget "$jarUrl" -O "$wrapperJarPath" + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + curl -o "$wrapperJarPath" "$jarUrl" + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/sm-shop/mvnw.cmd b/sm-shop/mvnw.cmd new file mode 100755 index 0000000000..48363fa60b --- /dev/null +++ b/sm-shop/mvnw.cmd @@ -0,0 +1,161 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar" +FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + echo Found %WRAPPER_JAR% +) else ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')" + echo Finished downloading %WRAPPER_JAR% +) +@REM End of extension + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/sm-shop/pom.xml b/sm-shop/pom.xml new file mode 100644 index 0000000000..a5287c6ad4 --- /dev/null +++ b/sm-shop/pom.xml @@ -0,0 +1,158 @@ + + + + 4.0.0 + + + com.shopizer + shopizer + 3.2.5 + + + sm-shop + sm-shop + http://www.shopizer.com + + + .04 + .01 + 1.3 + + + + + + com.shopizer + sm-core + + + + com.shopizer + sm-core-model + + + + com.shopizer + sm-shop-model + + + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.boot + spring-boot-starter-aop + + + + org.springframework.boot + spring-boot-starter-actuator + + + + com.google.guava + guava + + + + org.springframework.boot + spring-boot-starter-tomcat + provided + + + + org.apache.tomcat.embed + tomcat-embed-jasper + provided + + + + + + commons-collections + commons-collections + 3.2.2 + + + + + org.mapstruct + mapstruct + + + + + com.h2database + h2 + + + + io.jsonwebtoken + jjwt + + + + + io.springfox + springfox-swagger2 + + + + io.springfox + springfox-swagger-ui + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.security + spring-security-test + test + + + + + org.apache.commons + commons-rng-simple + ${commons-rng-simple.version} + + + + + + org.owasp.antisamy + antisamy + 1.6.7 + + + + + + org.passay + passay + 1.6.0 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + shopizer + + + jar + diff --git a/sm-shop/src/main/java/com/salesmanager/shop/admin/security/AbstractAuthenticatinSuccessHandler.java b/sm-shop/src/main/java/com/salesmanager/shop/admin/security/AbstractAuthenticatinSuccessHandler.java new file mode 100755 index 0000000000..735f736b78 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/admin/security/AbstractAuthenticatinSuccessHandler.java @@ -0,0 +1,65 @@ +package com.salesmanager.shop.admin.security; + +import java.util.Date; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; + +import com.salesmanager.core.business.services.user.UserService; +import com.salesmanager.core.model.user.User; + +public abstract class AbstractAuthenticatinSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { + + abstract protected void redirectAfterSuccess(HttpServletRequest request, HttpServletResponse response) throws Exception; + + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractAuthenticatinSuccessHandler.class); + + + @Inject + private UserService userService; + + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { + // last access timestamp + String userName = authentication.getName(); + + /** + * Spring Security 4 does not seem to add security context in the session + * creating the authentication to be lost during the login + */ + SecurityContext securityContext = SecurityContextHolder.getContext(); + HttpSession session = request.getSession(true); + session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext); + + try { + User user = userService.getByUserName(userName); + + Date lastAccess = user.getLoginTime(); + if(lastAccess==null) { + lastAccess = new Date(); + } + user.setLastAccess(lastAccess); + user.setLoginTime(new Date()); + + userService.saveOrUpdate(user); + + redirectAfterSuccess(request,response); + + + } catch (Exception e) { + LOGGER.error("User authenticationSuccess",e); + } + + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/admin/security/SecurityDataAccessException.java b/sm-shop/src/main/java/com/salesmanager/shop/admin/security/SecurityDataAccessException.java new file mode 100755 index 0000000000..9c095a5f9a --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/admin/security/SecurityDataAccessException.java @@ -0,0 +1,20 @@ +package com.salesmanager.shop.admin.security; + +import org.springframework.dao.DataAccessException; + +public class SecurityDataAccessException extends DataAccessException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public SecurityDataAccessException(String msg) { + super(msg); + } + + public SecurityDataAccessException(String msg, Exception e) { + super(msg,e); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/admin/security/UserAuthenticationSuccessHandler.java b/sm-shop/src/main/java/com/salesmanager/shop/admin/security/UserAuthenticationSuccessHandler.java new file mode 100755 index 0000000000..e925c421c5 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/admin/security/UserAuthenticationSuccessHandler.java @@ -0,0 +1,31 @@ +package com.salesmanager.shop.admin.security; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.web.DefaultRedirectStrategy; +import org.springframework.security.web.RedirectStrategy; + +public class UserAuthenticationSuccessHandler extends AbstractAuthenticatinSuccessHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(UserAuthenticationSuccessHandler.class); + + private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); + + + public void setRedirectStrategy(RedirectStrategy redirectStrategy) { + this.redirectStrategy = redirectStrategy; + } + protected RedirectStrategy getRedirectStrategy() { + return redirectStrategy; + } + + @Override + protected void redirectAfterSuccess(HttpServletRequest request, HttpServletResponse response) throws Exception { + redirectStrategy.sendRedirect(request, response, "/admin/home.html"); + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/admin/security/UserServicesImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/admin/security/UserServicesImpl.java new file mode 100755 index 0000000000..89480431ad --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/admin/security/UserServicesImpl.java @@ -0,0 +1,143 @@ +package com.salesmanager.shop.admin.security; + +import com.salesmanager.core.business.services.merchant.MerchantStoreService; +import com.salesmanager.core.business.services.user.GroupService; +import com.salesmanager.core.business.services.user.PermissionService; +import com.salesmanager.core.business.services.user.UserService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.model.user.GroupType; +import com.salesmanager.core.model.user.Permission; +import com.salesmanager.shop.constants.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.dao.DataAccessException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +import javax.inject.Inject; +import javax.inject.Named; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + + +/** + * + * @author casams1 + * http://stackoverflow.com/questions/5105776/spring-security-with + * -custom-user-details + */ +@Service("userDetailsService") +public class UserServicesImpl implements WebUserServices{ + + private static final Logger LOGGER = LoggerFactory.getLogger(UserServicesImpl.class); + + private static final String DEFAULT_INITIAL_PASSWORD = "password"; + + @Inject + private UserService userService; + + + @Inject + private MerchantStoreService merchantStoreService; + + @Inject + @Named("passwordEncoder") + private PasswordEncoder passwordEncoder; + + + + @Inject + protected PermissionService permissionService; + + @Inject + protected GroupService groupService; + + public final static String ROLE_PREFIX = "ROLE_"; + + + + public UserDetails loadUserByUsername(String userName) + throws UsernameNotFoundException, DataAccessException { + + com.salesmanager.core.model.user.User user = null; + Collection authorities = new ArrayList(); + + try { + + user = userService.getByUserName(userName); + + if(user==null) { + return null; + } + + GrantedAuthority role = new SimpleGrantedAuthority(ROLE_PREFIX + Constants.PERMISSION_AUTHENTICATED);//required to login + authorities.add(role); + + List groupsId = new ArrayList(); + List groups = user.getGroups(); + for(Group group : groups) { + + + groupsId.add(group.getId()); + + } + + + + List permissions = permissionService.getPermissions(groupsId); + for(Permission permission : permissions) { + GrantedAuthority auth = new SimpleGrantedAuthority(ROLE_PREFIX + permission.getPermissionName()); + authorities.add(auth); + } + + } catch (Exception e) { + LOGGER.error("Exception while querrying user",e); + throw new SecurityDataAccessException("Exception while querrying user",e); + } + + + + + + User secUser = new User(userName, user.getAdminPassword(), user.isActive(), true, + true, true, authorities); + return secUser; + } + + + public void createDefaultAdmin() throws Exception { + + MerchantStore store = merchantStoreService.getByCode(MerchantStore.DEFAULT_STORE); + + String password = passwordEncoder.encode(DEFAULT_INITIAL_PASSWORD); + + List groups = groupService.listGroup(GroupType.ADMIN); + + //creation of the super admin admin:password) + com.salesmanager.core.model.user.User user = new com.salesmanager.core.model.user.User("admin@shopizer.com",password,"admin@shopizer.com"); + user.setFirstName("Administrator"); + user.setLastName("User"); + + for(Group group : groups) { + if(group.getGroupName().equals(Constants.GROUP_SUPERADMIN) || group.getGroupName().equals(Constants.GROUP_ADMIN)) { + user.getGroups().add(group); + } + } + + user.setMerchantStore(store); + userService.create(user); + + + } + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/admin/security/WebUserServices.java b/sm-shop/src/main/java/com/salesmanager/shop/admin/security/WebUserServices.java new file mode 100755 index 0000000000..e047856de2 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/admin/security/WebUserServices.java @@ -0,0 +1,9 @@ +package com.salesmanager.shop.admin.security; + +import org.springframework.security.core.userdetails.UserDetailsService; + +public interface WebUserServices extends UserDetailsService{ + + void createDefaultAdmin() throws Exception; + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/application/ShopApplication.java b/sm-shop/src/main/java/com/salesmanager/shop/application/ShopApplication.java new file mode 100755 index 0000000000..dd91c2f7c8 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/application/ShopApplication.java @@ -0,0 +1,15 @@ +package com.salesmanager.shop.application; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; + + +@SpringBootApplication(exclude = { SecurityAutoConfiguration.class }) +public class ShopApplication { + + public static void main(String[] args) { + SpringApplication.run(ShopApplication.class, args); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/application/config/AsyncConfig.java b/sm-shop/src/main/java/com/salesmanager/shop/application/config/AsyncConfig.java new file mode 100755 index 0000000000..ffe649b174 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/application/config/AsyncConfig.java @@ -0,0 +1,28 @@ +package com.salesmanager.shop.application.config; + +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; +import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; + +@Configuration +@EnableScheduling +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + + private static final int EXECUTOR_SERVICE_NUMBER_THREADS = 5; + + @Override + public Executor getAsyncExecutor() { + return Executors.newFixedThreadPool(EXECUTOR_SERVICE_NUMBER_THREADS); + } + + @Override + public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { + return new SimpleAsyncUncaughtExceptionHandler(); + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/application/config/DocumentationConfiguration.java b/sm-shop/src/main/java/com/salesmanager/shop/application/config/DocumentationConfiguration.java new file mode 100755 index 0000000000..66da938c68 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/application/config/DocumentationConfiguration.java @@ -0,0 +1,111 @@ +package com.salesmanager.shop.application.config; + +import static io.swagger.models.auth.In.HEADER; +import static java.util.Collections.singletonList; +import static org.springframework.http.HttpHeaders.AUTHORIZATION; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.bind.annotation.RequestMethod; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; + +import springfox.documentation.RequestHandler; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.builders.ResponseMessageBuilder; +import springfox.documentation.schema.ModelRef; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.ApiKey; +import springfox.documentation.service.AuthorizationScope; +import springfox.documentation.service.Contact; +import springfox.documentation.service.ResponseMessage; +import springfox.documentation.service.SecurityReference; +import springfox.documentation.service.SecurityScheme; +import springfox.documentation.service.VendorExtension; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +@Configuration +@EnableSwagger2 +public class DocumentationConfiguration { + + public static final Contact DEFAULT_CONTACT = new Contact("Shopizer", "https://www.shopizer.com", ""); + + private static final String HOST = "localhost:8080"; + + /** + * http://localhost:8080/swagger-ui.html#/ http://localhost:8080/v2/api-docs + */ + + @Bean + public Docket api() { + + final List getMessages = new ArrayList(); + getMessages.add(new ResponseMessageBuilder().code(500).message("500 message") + .responseModel(new ModelRef("Error")).build()); + getMessages.add(new ResponseMessageBuilder().code(403).message("Forbidden").build()); + getMessages.add(new ResponseMessageBuilder().code(401).message("Unauthorized").build()); + + Set produces = new HashSet<>(); + produces.add("application/json"); + + Set consumes = new HashSet<>(); + consumes.add("application/json"); + + return new Docket(DocumentationType.SWAGGER_2) + .host(HOST) + .select() + .apis(requestHandlers()).build() + .securitySchemes(Collections.singletonList(new ApiKey("JWT", AUTHORIZATION, HEADER.name()))) + .securityContexts(singletonList( + SecurityContext.builder() + .securityReferences( + singletonList(SecurityReference.builder() + .reference("JWT") + .scopes(new AuthorizationScope[0]) + .build() + ) + ) + .build()) + ) + .produces(produces).consumes(consumes).globalResponseMessage(RequestMethod.GET, getMessages) + .globalResponseMessage(RequestMethod.GET, getMessages); + + } + + final Predicate requestHandlers() { + + Set> matchers = new HashSet>(); + matchers.add(RequestHandlerSelectors.basePackage("com.salesmanager.shop.store.api.v1")); + matchers.add(RequestHandlerSelectors.basePackage("com.salesmanager.shop.store.api.v2")); + + return Predicates.or(matchers); + + } + + @SuppressWarnings("rawtypes") + private ApiInfo apiInfo() { + return new ApiInfo("Shopizer REST API", + "API for Shopizer e-commerce. Contains public end points as well as private end points requiring basic authentication and remote authentication based on jwt bearer token. URL patterns containing /private/** use bearer token; those are authorized customer and administrators administration actions.", + "1.0", "urn:tos", DEFAULT_CONTACT, "Apache 2.0", "http://www.apache.org/licenses/LICENSE-2.0", + new ArrayList()); + + } + + private static ArrayList securitySchemes() { + return (ArrayList) Stream.of(new ApiKey("Bearer", "Authorization", "header")) + .collect(Collectors.toList()); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/application/config/LanguageArgumentResolver.java b/sm-shop/src/main/java/com/salesmanager/shop/application/config/LanguageArgumentResolver.java new file mode 100755 index 0000000000..5496a7fa6d --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/application/config/LanguageArgumentResolver.java @@ -0,0 +1,37 @@ +package com.salesmanager.shop.application.config; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.utils.LanguageUtils; + +@Component +public class LanguageArgumentResolver implements HandlerMethodArgumentResolver { + + + @Autowired + private LanguageUtils languageUtils; + + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.getParameterType().equals(Language.class); + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { + + HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); + + return languageUtils.getRESTLanguage(request, webRequest); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/application/config/LocationImageConfig.java b/sm-shop/src/main/java/com/salesmanager/shop/application/config/LocationImageConfig.java new file mode 100644 index 0000000000..98a6338a31 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/application/config/LocationImageConfig.java @@ -0,0 +1,47 @@ +package com.salesmanager.shop.application.config; + +import org.drools.core.util.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.salesmanager.shop.utils.CloudFilePathUtils; +import com.salesmanager.shop.utils.ImageFilePath; +import com.salesmanager.shop.utils.LocalImageFilePathUtils; + +@Configuration +public class LocationImageConfig { + + @Value("${config.cms.contentUrl}") + private String contentUrl; + + @Value("${config.cms.method}") + private String method; + + @Value("${config.cms.static.path}") + private String staticPath; + + + @Bean + public ImageFilePath img() { + + if(!StringUtils.isEmpty(method) && !method.equals("default")) { + CloudFilePathUtils cloudFilePathUtils = new CloudFilePathUtils(); + cloudFilePathUtils.setBasePath(contentUrl); + cloudFilePathUtils.setContentUrlPath(contentUrl); + return cloudFilePathUtils; + + } else { + + + LocalImageFilePathUtils localImageFilePathUtils = new LocalImageFilePathUtils(); + localImageFilePathUtils.setBasePath(staticPath); + localImageFilePathUtils.setContentUrlPath(contentUrl); + return localImageFilePathUtils; + } + + + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/application/config/MerchantStoreArgumentResolver.java b/sm-shop/src/main/java/com/salesmanager/shop/application/config/MerchantStoreArgumentResolver.java new file mode 100755 index 0000000000..c4a593ad07 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/application/config/MerchantStoreArgumentResolver.java @@ -0,0 +1,62 @@ +package com.salesmanager.shop.application.config; + +import static com.salesmanager.core.business.constants.Constants.DEFAULT_STORE; + +import java.util.Optional; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.shop.store.api.exception.UnauthorizedException; +import com.salesmanager.shop.store.controller.store.facade.StoreFacade; +import com.salesmanager.shop.store.controller.user.facade.UserFacade; + +@Component +public class MerchantStoreArgumentResolver implements HandlerMethodArgumentResolver { + + private static final Logger LOGGER = LoggerFactory.getLogger(MerchantStoreArgumentResolver.class); + public static final String REQUEST_PARAMATER_STORE = "store"; + + @Autowired + private StoreFacade storeFacade; + + @Autowired + private UserFacade userFacade; + + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.getParameterType().equals(MerchantStore.class); + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { + String storeValue = Optional.ofNullable(webRequest.getParameter(REQUEST_PARAMATER_STORE)) + .filter(StringUtils::isNotBlank).orElse(DEFAULT_STORE); + // todo get from cache + MerchantStore storeModel = storeFacade.get(storeValue); + + HttpServletRequest httpServletRequest = webRequest.getNativeRequest(HttpServletRequest.class); + + // TODO Move to an api filter + // authorize request + boolean authorized = userFacade.authorizeStore(storeModel, httpServletRequest.getRequestURI()); + LOGGER.debug("is request authorized {} for {} and store {}", authorized, httpServletRequest.getRequestURI(), + storeModel.getCode()); + if(!authorized){ + throw new UnauthorizedException("Cannot authorize user for store " + storeModel.getCode()); + } + return storeModel; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/application/config/MethodSecurityConfig.java b/sm-shop/src/main/java/com/salesmanager/shop/application/config/MethodSecurityConfig.java new file mode 100755 index 0000000000..9ad0b62f13 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/application/config/MethodSecurityConfig.java @@ -0,0 +1,14 @@ +package com.salesmanager.shop.application.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; + +@Configuration +@EnableGlobalMethodSecurity( + prePostEnabled = true, + securedEnabled = true, + jsr250Enabled = true) +public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/application/config/MultipleEntryPointsSecurityConfig.java b/sm-shop/src/main/java/com/salesmanager/shop/application/config/MultipleEntryPointsSecurityConfig.java new file mode 100755 index 0000000000..cc793956ac --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/application/config/MultipleEntryPointsSecurityConfig.java @@ -0,0 +1,428 @@ +package com.salesmanager.shop.application.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; + +import com.salesmanager.shop.admin.security.UserAuthenticationSuccessHandler; +import com.salesmanager.shop.admin.security.WebUserServices; +import com.salesmanager.shop.store.controller.customer.facade.CustomerFacade; +import com.salesmanager.shop.store.security.AuthenticationTokenFilter; +import com.salesmanager.shop.store.security.ServicesAuthenticationSuccessHandler; +import com.salesmanager.shop.store.security.admin.JWTAdminAuthenticationProvider; +import com.salesmanager.shop.store.security.admin.JWTAdminServicesImpl; +import com.salesmanager.shop.store.security.customer.JWTCustomerAuthenticationProvider; +import com.salesmanager.shop.store.security.services.CredentialsService; +import com.salesmanager.shop.store.security.services.CredentialsServiceImpl; + +/** + * Main entry point for security - admin - customer - auth - private - services + * + * @author dur9213 + * + */ +@Configuration +@EnableWebSecurity +public class MultipleEntryPointsSecurityConfig { + + private static final String API_VERSION = "/api/v*"; + + @Bean + public AuthenticationTokenFilter authenticationTokenFilter() { + return new AuthenticationTokenFilter(); + } + + @Bean + public CredentialsService credentialsService() { + return new CredentialsServiceImpl(); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public UserAuthenticationSuccessHandler userAuthenticationSuccessHandler() { + return new UserAuthenticationSuccessHandler(); + } + + @Bean + public ServicesAuthenticationSuccessHandler servicesAuthenticationSuccessHandler() { + return new ServicesAuthenticationSuccessHandler(); + } + + @Bean + public CustomerFacade customerFacade() { + return new com.salesmanager.shop.store.controller.customer.facade.CustomerFacadeImpl(); + } + + + + /** + * shop / customer + * + * @author dur9213 + * + */ + @Configuration + @Order(1) + public static class CustomerConfigurationAdapter extends WebSecurityConfigurerAdapter { + + @Bean("customerAuthenticationManager") + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Autowired + private UserDetailsService customerDetailsService; + + public CustomerConfigurationAdapter() { + super(); + } + + @Override + public void configure(WebSecurity web) { + web.ignoring().antMatchers("/"); + web.ignoring().antMatchers("/error"); + web.ignoring().antMatchers("/resources/**"); + web.ignoring().antMatchers("/static/**"); + web.ignoring().antMatchers("/services/public/**"); + } + + + @Override + public void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(customerDetailsService); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .antMatcher("/shop/**") + .csrf().disable() + .authorizeRequests() + .antMatchers("/shop/").permitAll() + .antMatchers("/shop/**").permitAll() + .antMatchers("/shop/customer/logon*").permitAll() + .antMatchers("/shop/customer/registration*").permitAll() + .antMatchers("/shop/customer/logout*").permitAll() + .antMatchers("/shop/customer/customLogon*").permitAll() + .antMatchers("/shop/customer/denied*").permitAll() + .antMatchers("/shop/customer/**").hasRole("AUTH_CUSTOMER") + .anyRequest().authenticated() + .and() + .httpBasic() + .authenticationEntryPoint(shopAuthenticationEntryPoint()) + .and() + .logout() + .logoutUrl("/shop/customer/logout") + .logoutSuccessUrl("/shop/") + .invalidateHttpSession(true) + .deleteCookies("JSESSIONID") + + .invalidateHttpSession(false) + .and() + .exceptionHandling().accessDeniedPage("/shop/"); + + } + + @Bean + public AuthenticationEntryPoint shopAuthenticationEntryPoint() { + BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint(); + entryPoint.setRealmName("shop-realm"); + return entryPoint; + } + + } + + /** + * services api v0 + * + * @author dur9213 + * @deprecated + * + */ + @Configuration + @Order(2) + public static class ServicesApiConfigurationAdapter extends WebSecurityConfigurerAdapter { + + @Autowired + private WebUserServices userDetailsService; + + @Autowired + private ServicesAuthenticationSuccessHandler servicesAuthenticationSuccessHandler; + + public ServicesApiConfigurationAdapter() { + super(); + } + + @Override + public void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailsService); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .antMatcher("/services/**") + .csrf().disable() + .authorizeRequests() + .antMatchers("/services/public/**").permitAll() + .antMatchers("/services/private/**").hasRole("AUTH") + .anyRequest().authenticated() + .and().httpBasic().authenticationEntryPoint(servicesAuthenticationEntryPoint()) + .and().formLogin() + .successHandler(servicesAuthenticationSuccessHandler); + + } + + @Bean + public AuthenticationEntryPoint servicesAuthenticationEntryPoint() { + BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint(); + entryPoint.setRealmName("rest-customer-realm"); + return entryPoint; + } + + } + + /** + * admin + * + * @author dur9213 + * + */ + /** + @Configuration + @Order(3) + public static class AdminConfigurationAdapter extends WebSecurityConfigurerAdapter { + + @Autowired + private WebUserServices userDetailsService; + + @Autowired + private UserAuthenticationSuccessHandler userAuthenticationSuccessHandler; + + public AdminConfigurationAdapter() { + super(); + } + + @Override + public void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailsService); + } + + @Override + public void configure(WebSecurity web) { + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .antMatcher("/admin/**") + .authorizeRequests() + .antMatchers("/admin/logon*").permitAll() + .antMatchers("/admin/resources/**").permitAll() + .antMatchers("/admin/layout/**").permitAll() + .antMatchers("/admin/denied*").permitAll() + .antMatchers("/admin/unauthorized*").permitAll() + .antMatchers("/admin/users/resetPassword*").permitAll() + .antMatchers("/admin/").hasRole("AUTH") + .antMatchers("/admin/**").hasRole("AUTH") + .antMatchers("/admin/**").hasRole("AUTH") + .antMatchers("/admin/users/resetPasswordSecurityQtn*").permitAll() + .anyRequest() + .authenticated() + .and() + .httpBasic() + .authenticationEntryPoint(adminAuthenticationEntryPoint()) + .and() + .formLogin().usernameParameter("username").passwordParameter("password") + .loginPage("/admin/logon.html") + .loginProcessingUrl("/admin/performUserLogin") + .successHandler(userAuthenticationSuccessHandler) + .failureUrl("/admin/logon.html?login_error=true") + .and() + .csrf().disable() + .logout().logoutUrl("/admin/logout").logoutSuccessUrl("/admin/home.html") + .invalidateHttpSession(true).and().exceptionHandling().accessDeniedPage("/admin/denied.html"); + + + } + + @Bean + public AuthenticationEntryPoint adminAuthenticationEntryPoint() { + BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint(); + entryPoint.setRealmName("admin-realm"); + return entryPoint; + } + + } + **/ + + /** + * api - private + * + * @author dur9213 + * + */ + @Configuration + @Order(5) + public static class UserApiConfigurationAdapter extends WebSecurityConfigurerAdapter { + + @Autowired + private AuthenticationTokenFilter authenticationTokenFilter; + + @Autowired + JWTAdminServicesImpl jwtUserDetailsService; + + @Bean("jwtAdminAuthenticationManager") + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + AuthenticationManager mgr = super.authenticationManagerBean(); + return mgr; + } + + + + public UserApiConfigurationAdapter() { + super(); + } + + @Override + public void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(jwtUserDetailsService) + .and() + .authenticationProvider(authenticationProvider()); + } + + @Override + public void configure(WebSecurity web) { + web.ignoring().antMatchers("/swagger-ui.html"); + } + + + /** + * Admin user api + */ + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .antMatcher(API_VERSION + "/private/**") + .authorizeRequests() + .antMatchers(API_VERSION + "/private/login*").permitAll() + .antMatchers(API_VERSION + "/private/refresh").permitAll() + .antMatchers(HttpMethod.OPTIONS, API_VERSION + "/private/**").permitAll() + .antMatchers(API_VERSION + "/private/**").hasRole("AUTH") + .anyRequest().authenticated() + .and() + .httpBasic().authenticationEntryPoint(apiAdminAuthenticationEntryPoint()) + .and() + .addFilterAfter(authenticationTokenFilter, BasicAuthenticationFilter.class) + .csrf().disable(); + + } + + @Bean + public AuthenticationProvider authenticationProvider() { + JWTAdminAuthenticationProvider provider = new JWTAdminAuthenticationProvider(); + provider.setUserDetailsService(jwtUserDetailsService); + return provider; + } + + @Bean + public AuthenticationEntryPoint apiAdminAuthenticationEntryPoint() { + BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint(); + entryPoint.setRealmName("api-admin-realm"); + return entryPoint; + } + + } + + + + /** + * customer api + * + * @author dur9213 + * + */ + @Configuration + @Order(6) + public static class CustomeApiConfigurationAdapter extends WebSecurityConfigurerAdapter { + + @Autowired + private AuthenticationTokenFilter authenticationTokenFilter; + + @Autowired + private UserDetailsService jwtCustomerDetailsService; + + public CustomeApiConfigurationAdapter() { + super(); + } + + @Bean("jwtCustomerAuthenticationManager") + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Override + public void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(jwtCustomerDetailsService); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + + .antMatcher(API_VERSION + "/auth/**") + .authorizeRequests() + .antMatchers(API_VERSION + "/auth/refresh").permitAll() + .antMatchers(API_VERSION + "/auth/login").permitAll() + .antMatchers(API_VERSION + "/auth/register").permitAll() + .antMatchers(HttpMethod.OPTIONS, API_VERSION + "/auth/**").permitAll() + .antMatchers(API_VERSION + "/auth/**") + .hasRole("AUTH_CUSTOMER").anyRequest().authenticated() + .and() + .httpBasic() + .authenticationEntryPoint(apiCustomerAuthenticationEntryPoint()).and().csrf().disable() + .addFilterAfter(authenticationTokenFilter, BasicAuthenticationFilter.class); + + } + + @Bean + public AuthenticationProvider authenticationProvider() { + JWTCustomerAuthenticationProvider provider = new JWTCustomerAuthenticationProvider(); + provider.setUserDetailsService(jwtCustomerDetailsService); + return provider; + } + + @Bean + public AuthenticationEntryPoint apiCustomerAuthenticationEntryPoint() { + BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint(); + entryPoint.setRealmName("api-customer-realm"); + return entryPoint; + } + + } + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/application/config/ShopApplicationConfiguration.java b/sm-shop/src/main/java/com/salesmanager/shop/application/config/ShopApplicationConfiguration.java new file mode 100755 index 0000000000..41f81a6604 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/application/config/ShopApplicationConfiguration.java @@ -0,0 +1,151 @@ +package com.salesmanager.shop.application.config; + +import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM; +import static org.springframework.http.MediaType.IMAGE_GIF; +import static org.springframework.http.MediaType.IMAGE_JPEG; +import static org.springframework.http.MediaType.IMAGE_PNG; + +import java.util.Arrays; +import java.util.List; +import java.util.Locale; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.event.EventListener; +import org.springframework.context.support.ReloadableResourceBundleMessageSource; +import org.springframework.http.MediaType; +import org.springframework.http.converter.ByteArrayHttpMessageConverter; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; +import org.springframework.web.servlet.i18n.SessionLocaleResolver; + +import com.salesmanager.core.business.configuration.CoreApplicationConfiguration; +import com.salesmanager.shop.filter.CorsFilter; +import com.salesmanager.shop.filter.XssFilter; +import com.salesmanager.shop.utils.LabelUtils; + +@Configuration +@ComponentScan({"com.salesmanager.shop"}) +@ServletComponentScan +@Import({CoreApplicationConfiguration.class}) // import sm-core configurations +@EnableWebSecurity +public class ShopApplicationConfiguration implements WebMvcConfigurer { + + protected final Log logger = LogFactory.getLog(getClass()); + + @EventListener(ApplicationReadyEvent.class) + public void applicationReadyCode() { + String workingDir = System.getProperty("user.dir"); + logger.info("Current working directory : " + workingDir); + } + + @Bean + public FilterRegistrationBean croseSiteFilter(){ + FilterRegistrationBean registrationBean + = new FilterRegistrationBean<>(); + + registrationBean.setFilter(new XssFilter()); + registrationBean.addUrlPatterns("/shop/**"); + registrationBean.addUrlPatterns("/api/**"); + registrationBean.addUrlPatterns("/customer/**"); + + return registrationBean; + } + + @Override + public void configureMessageConverters(List> converters) { + converters.add(new MappingJackson2HttpMessageConverter()); + } + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/").setViewName("shop"); + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + // Changes the locale when a 'locale' request parameter is sent; e.g. /?locale=de + registry.addInterceptor(localeChangeInterceptor()); + + /** + registry + .addInterceptor(storeFilter()) + // store web front filter + .addPathPatterns("/shop/**") + // customer section filter + .addPathPatterns("/customer/**"); + **/ + + registry + .addInterceptor(corsFilter()) + // public services cors filter + .addPathPatterns("/services/**") + // REST api + .addPathPatterns("/api/**"); + + } + + @Bean + public ByteArrayHttpMessageConverter byteArrayHttpMessageConverter() { + List supportedMediaTypes = Arrays.asList(IMAGE_JPEG, IMAGE_GIF, IMAGE_PNG, APPLICATION_OCTET_STREAM); + + ByteArrayHttpMessageConverter byteArrayHttpMessageConverter = + new ByteArrayHttpMessageConverter(); + byteArrayHttpMessageConverter.setSupportedMediaTypes(supportedMediaTypes); + return byteArrayHttpMessageConverter; + } + + @Bean + public LocaleChangeInterceptor localeChangeInterceptor() { + return new LocaleChangeInterceptor(); + } + + /* + * @Bean public StoreFilter storeFilter() { return new StoreFilter(); } + */ + + @Bean + public CorsFilter corsFilter() { + return new CorsFilter(); + } + + + @Bean + public SessionLocaleResolver localeResolver() { + SessionLocaleResolver slr = new SessionLocaleResolver(); + slr.setDefaultLocale(Locale.getDefault()); + return slr; + } + + @Bean + public ReloadableResourceBundleMessageSource messageSource() { + ReloadableResourceBundleMessageSource messageSource = + new ReloadableResourceBundleMessageSource(); + messageSource.setBasenames( + "classpath:bundles/shopizer", + "classpath:bundles/messages", + "classpath:bundles/shipping", + "classpath:bundles/payment"); + + messageSource.setDefaultEncoding("UTF-8"); + return messageSource; + } + + @Bean + public LabelUtils messages() { + return new LabelUtils(); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/application/config/ShopServletContextListener.java b/sm-shop/src/main/java/com/salesmanager/shop/application/config/ShopServletContextListener.java new file mode 100755 index 0000000000..c4aec382bf --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/application/config/ShopServletContextListener.java @@ -0,0 +1,32 @@ +package com.salesmanager.shop.application.config; + +import com.salesmanager.core.business.modules.cms.impl.VendorCacheManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.Properties; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; + +@WebListener +public class ShopServletContextListener implements ServletContextListener { + private static final Logger logger = LoggerFactory.getLogger(ShopServletContextListener.class); + @Override + public void contextInitialized(ServletContextEvent servletContextEvent) { + logger.info("===context init==="); + System.getenv().forEach((k, v) -> { + logger.debug(k + ":" + v); + }); + Properties props = System.getProperties(); + props.forEach((k, v) -> { + logger.debug(k + ":" + v); + }); + } + + @Override + public void contextDestroyed(ServletContextEvent servletContextEvent) { + logger.info("===context destroy==="); + VendorCacheManager cacheManager = VendorCacheManager.getInstance(); + cacheManager.getManager().stop(); + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/application/config/ShopizerPropertiesConfig.java b/sm-shop/src/main/java/com/salesmanager/shop/application/config/ShopizerPropertiesConfig.java new file mode 100755 index 0000000000..b60a695bae --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/application/config/ShopizerPropertiesConfig.java @@ -0,0 +1,18 @@ +package com.salesmanager.shop.application.config; + + +import org.springframework.beans.factory.config.PropertiesFactoryBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; + +@Configuration +public class ShopizerPropertiesConfig { + + @Bean(name = "shopizer-properties") + public PropertiesFactoryBean mapper() { + PropertiesFactoryBean bean = new PropertiesFactoryBean(); + bean.setLocation(new ClassPathResource("shopizer-properties.properties")); + return bean; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/application/config/WebConfig.java b/sm-shop/src/main/java/com/salesmanager/shop/application/config/WebConfig.java new file mode 100644 index 0000000000..9cf3b3aa02 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/application/config/WebConfig.java @@ -0,0 +1,29 @@ +package com.salesmanager.shop.application.config; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + + +@Configuration +public class WebConfig implements WebMvcConfigurer { + + + @Autowired + private MerchantStoreArgumentResolver merchantStoreArgumentResolver; + + @Autowired + private LanguageArgumentResolver languageArgumentResolver; + + + @Override + public void addArgumentResolvers(List argumentResolvers) { + argumentResolvers.add(merchantStoreArgumentResolver); + argumentResolvers.add(languageArgumentResolver); + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/constants/ApplicationConstants.java b/sm-shop/src/main/java/com/salesmanager/shop/constants/ApplicationConstants.java new file mode 100755 index 0000000000..be0a6ee780 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/constants/ApplicationConstants.java @@ -0,0 +1,11 @@ +package com.salesmanager.shop.constants; + +public class ApplicationConstants { + + public final static String POPULATE_TEST_DATA = "POPULATE_TEST_DATA"; + public final static String TEST_DATA_LOADED = "TEST_DATA_LOADED"; + public final static String RECAPTCHA_URL = "shopizer.recapatcha_url"; + public final static String SHOP_SCHEME= "SHOP_SCHEME"; + public final static int MAX_DOWNLOAD_DAYS = 30; + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/constants/Constants.java b/sm-shop/src/main/java/com/salesmanager/shop/constants/Constants.java new file mode 100755 index 0000000000..de70533b5a --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/constants/Constants.java @@ -0,0 +1,133 @@ +package com.salesmanager.shop.constants; + +public class Constants { + + public final static String DEFAULT_TEMPLATE = "december"; + + public final static String SLASH = "/"; + public final static String BLANK = ""; + public final static String EQUALS = "="; + + public final static String RESPONSE_STATUS = "STATUS"; + public final static String RESPONSE_SUCCESS = "SUCCESS"; + public final static String DEFAULT_LANGUAGE = "en"; + public final static String LANGUAGE = "LANGUAGE"; + public final static String LOCALE = "LOCALE"; + public final static String LANG = "lang"; + public final static String BREADCRUMB = "BREADCRUMB"; + + public final static String HOME_MENU_KEY = "menu.home"; + public final static String HOME_URL = "/shop"; + public final static String ADMIN_URI = "/admin"; + public final static String SHOP_URI = "/shop"; + public final static String SHOP = "shop"; + public final static String REF = "ref"; + public final static String REF_C = "c:"; + public final static String REF_SPLITTER = ":"; + + public final static String FILE_NOT_FOUND = "File not found"; + + + + public final static String DEFAULT_DOMAIN_NAME = "localhost:8080"; + + public final static String ADMIN_STORE = "ADMIN_STORE"; + public final static String ADMIN_USER = "ADMIN_USER"; + public final static String MERCHANT_STORE = "MERCHANT_STORE"; + public final static String SHOPPING_CART = "SHOPPING_CART"; + public final static String CUSTOMER = "CUSTOMER"; + public final static String ORDER = "ORDER"; + public final static String ORDER_ID = "ORDER_ID"; + public final static String ORDER_ID_TOKEN = "ORDER_ID_TOKEN"; + public final static String SHIPPING_SUMMARY = "SHIPPING_SUMMARY"; + public final static String SHIPPING_OPTIONS = "SHIPPING_OPTIONS"; + public final static String ORDER_SUMMARY = "ORDER_SIMMARY"; + + + public final static String GROUP_ADMIN = "ADMIN"; + public final static String PERMISSION_AUTHENTICATED = "AUTH"; + public final static String PERMISSION_CUSTOMER_AUTHENTICATED = "AUTH_CUSTOMER"; + public final static String GROUP_SUPERADMIN = "SUPERADMIN"; + public final static String GROUP_ADMIN_CATALOGUE = "ADMIN_CATALOGUE"; + public final static String GROUP_ADMIN_ORDER = "ADMIN_ORDER"; + public final static String GROUP_ADMIN_RETAIL = "ADMIN_RETAIL"; + public final static String GROUP_CUSTOMER = "CUSTOMER"; + public final static String GROUP_SHIPPING = "SHIPPING"; + public final static String ANONYMOUS_CUSTOMER = "ANONYMOUS_CUSTOMER"; + + + public final static String CONTENT_IMAGE = "CONTENT"; + public final static String CONTENT_LANDING_PAGE = "LANDING_PAGE"; + public final static String CONTENT_CONTACT_US = "contact"; + + public final static String STATIC_URI = "/static"; + public final static String FILES_URI = "/files"; + public final static String PRODUCT_URI= "/product"; + public final static String PRODUCTS_URI= "/products"; + public final static String SMALL_IMAGE= "SMALL"; + public final static String LARGE_IMAGE= "LARGE"; + public final static String CATEGORY_URI = "/category"; + public final static String PRODUCT_ID_URI= "/productid"; + public final static String ORDER_DOWNLOAD_URI= "/order/download"; + + public final static String URL_EXTENSION= ".html"; + public final static String REDIRECT_PREFIX ="redirect:"; + + + + + public final static String STORE_CONFIGURATION = "STORECONFIGURATION"; + + public final static String HTTP_SCHEME= "http"; + + public final static String SHOP_SCHEME = "SHOP_SCHEME"; + public final static String FACEBOOK_APP_ID = "shopizer.facebook-appid"; + + public final static String MISSED_CACHE_KEY = "MISSED"; + public final static String CONTENT_CACHE_KEY = "CONTENT"; + public final static String CONTENT_PAGE_CACHE_KEY = "CONTENT_PAGE"; + public final static String CATEGORIES_CACHE_KEY = "CATALOG_CATEGORIES"; + public final static String PRODUCTS_GROUP_CACHE_KEY = "CATALOG_GROUP"; + public final static String SUBCATEGORIES_CACHE_KEY = "CATALOG_SUBCATEGORIES"; + public final static String RELATEDITEMS_CACHE_KEY = "CATALOG_RELATEDITEMS"; + public final static String MANUFACTURERS_BY_PRODUCTS_CACHE_KEY = "CATALOG_BRANDS_BY_PRODUCTS"; + public final static String CONFIG_CACHE_KEY = "CONFIG"; + + public final static String REQUEST_CONTENT_OBJECTS = "CONTENT"; + public final static String REQUEST_CONTENT_PAGE_OBJECTS = "CONTENT_PAGE"; + public final static String REQUEST_TOP_CATEGORIES = "TOP_CATEGORIES"; + public final static String REQUEST_PAGE_INFORMATION = "PAGE_INFORMATION"; + public final static String REQUEST_SHOPPING_CART = "SHOPPING_CART"; + public final static String REQUEST_CONFIGS = "CONFIGS"; + + public final static String KEY_FACEBOOK_PAGE_URL = "facebook_page_url"; + public final static String KEY_PINTEREST_PAGE_URL = "pinterest"; + public final static String KEY_GOOGLE_ANALYTICS_URL = "google_analytics_url"; + public final static String KEY_INSTAGRAM_URL = "instagram"; + public final static String KEY_GOOGLE_API_KEY = "google_api_key"; + public final static String KEY_TWITTER_HANDLE = "twitter_handle"; + public final static String KEY_SESSION_ADDRESS = "readableDelivery"; + + public final static String CATEGORY_LINEAGE_DELIMITER = "/"; + public final static int MAX_REVIEW_RATING_SCORE = 5; + public final static int MAX_ORDERS_PAGE = 5; + public final static String SUCCESS = "success"; + public final static String CANCEL = "cancel"; + + public final static String START = "start"; + public final static String MAX = "max"; + + public final static String CREDIT_CARD_YEARS_CACHE_KEY = "CREDIT_CARD_YEARS_CACHE_KEY"; + public final static String MONTHS_OF_YEAR_CACHE_KEY = "MONTHS_OF_YEAR_CACHE_KEY"; + + public final static String INIT_TRANSACTION_KEY = "init_transaction"; + + public final static String LINK_CODE = "LINK_CODE"; + + public final static String COOKIE_NAME_USER = "user"; + public final static String COOKIE_NAME_CART = "cart"; + public final static String RESPONSE_KEY_USERNAME = "userName"; + + public final static String DEBUG_MODE = "debugMode"; + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/constants/EmailConstants.java b/sm-shop/src/main/java/com/salesmanager/shop/constants/EmailConstants.java new file mode 100755 index 0000000000..f811d7ecfc --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/constants/EmailConstants.java @@ -0,0 +1,90 @@ +package com.salesmanager.shop.constants; + +public class EmailConstants { + + public static final String EMAIL_NEW_USER_TEXT = "EMAIL_NEW_USER_TEXT"; + public static final String EMAIL_USER_FIRSTNAME = "EMAIL_USER_FIRSTNAME"; + public static final String EMAIL_USER_LASTNAME = "EMAIL_USER_LASTNAME"; + public static final String EMAIL_ADMIN_USERNAME_LABEL = "EMAIL_ADMIN_USERNAME_LABEL"; + public static final String EMAIL_ADMIN_NAME = "EMAIL_ADMIN_NAME"; + public static final String EMAIL_TEXT_NEW_USER_CREATED = "EMAIL_TEXT_NEW_USER_CREATED"; + public static final String EMAIL_ADMIN_PASSWORD_LABEL = "EMAIL_ADMIN_PASSWORD_LABEL"; + public static final String EMAIL_ADMIN_PASSWORD = "EMAIL_ADMIN_PASSWORD"; + + + public static final String EMAIL_USERNAME_LABEL = "EMAIL_USERNAME_LABEL"; + public static final String EMAIL_PASSWORD_LABEL = "EMAIL_PASSWORD_LABEL"; + public static final String EMAIL_CUSTOMER_PASSWORD = "EMAIL_CUSTOMER_PASSWORD"; + public static final String EMAIL_CUSTOMER_NAME = "EMAIL_CUSTOMER_NAME"; + public static final String EMAIL_CUSTOMER_FIRSTNAME = "EMAIL_CUSTOMER_FIRSTNAME"; + public static final String EMAIL_CUSTOMER_LASTNAME = "EMAIL_CUSTOMER_LASTNAME"; + public static final String EMAIL_NOTIFICATION_MESSAGE = "EMAIL_NOTIFICATION_MESSAGE"; + public static final String EMAIL_CUSTOMER_GREETING = "EMAIL_CUSTOMER_GREETING"; + public static final String EMAIL_RESET_PASSWORD_TXT = "EMAIL_RESET_PASSWORD_TXT"; + public static final String EMAIL_USER_NAME = "EMAIL_USER_NAME"; + public static final String EMAIL_USER_PASSWORD = "EMAIL_USER_PASSWORD"; + + public static final String EMAIL_TEXT_ORDER_NUMBER = "EMAIL_TEXT_ORDER_NUMBER"; + public static final String EMAIL_TEXT_DATE_ORDERED = "EMAIL_TEXT_DATE_ORDERED"; + public static final String EMAIL_TEXT_STATUS_COMMENTS = "EMAIL_TEXT_STATUS_COMMENTS"; + public static final String EMAIL_TEXT_DATE_UPDATED = "EMAIL_TEXT_DATE_UPDATED"; + public static final String EMAIL_ORDER_DETAILS_TITLE = "EMAIL_ORDER_DETAILS_TITLE"; + public static final String ORDER_PRODUCTS_DETAILS = "ORDER_PRODUCTS_DETAILS"; + public static final String ORDER_TOTALS = "ORDER_TOTALS"; + public static final String ORDER_STATUS = "ORDER_STATUS"; + public final static String EMAIL_ORDER_DOWNLOAD = "EMAIL_ORDER_DOWNLOAD"; + + public static final String EMAIL_NEW_STORE_TEXT = "EMAIL_NEW_STORE_TEXT"; + public static final String EMAIL_STORE_NAME = "EMAIL_STORE_NAME"; + public static final String EMAIL_ADMIN_STORE_INFO_LABEL = "EMAIL_ADMIN_STORE_INFO_LABEL"; + public static final String EMAIL_ADMIN_USERNAME_TEXT = "EMAIL_ADMIN_USERNAME_TEXT"; + public static final String EMAIL_ADMIN_PASSWORD_TEXT = "EMAIL_ADMIN_PASSWORD_TEXT"; + + + + public static final String EMAIL_CONTACT_OWNER = "EMAIL_CONTACT_OWNER"; + public static final String EMAIL_ADMIN_URL_LABEL = "EMAIL_ADMIN_URL_LABEL"; + public static final String EMAIL_ADMIN_URL = "EMAIL_ADMIN_URL"; + + public static final String EMAIL_ORDER_CONFIRMATION_TITLE ="EMAIL_ORDER_CONFIRMATION_TITLE"; + public static final String EMAIL_ORDER_NUMBER ="EMAIL_ORDER_NUMBER"; + public static final String EMAIL_ORDER_DATE ="EMAIL_ORDER_DATE"; + public static final String EMAIL_ORDER_THANKS ="EMAIL_ORDER_THANKS"; + public static final String EMAIL_ORDER_STATUS_TEXT ="EMAIL_ORDER_STATUS_TEXT"; + public static final String EMAIL_ORDER_STATUS ="EMAIL_ORDER_STATUS"; + public static final String ADDRESS_BILLING_TITLE ="ADDRESS_BILLING_TITLE"; + public static final String ADDRESS_BILLING ="ADDRESS_BILLING"; + public static final String ADDRESS_SHIPPING ="ADDRESS_SHIPPING"; + public static final String ADDRESS_DELIVERY ="ADDRESS_DELIVERY"; + public static final String ADDRESS_SHIPPING_TITLE ="ADDRESS_SHIPPING_TITLE"; + public static final String PAYMENT_METHOD_TITLE ="PAYMENT_METHOD_TITLE"; + public static final String PAYMENT_METHOD_DETAILS ="PAYMENT_METHOD_DETAILS"; + public static final String SHIPPING_METHOD_DETAILS ="SHIPPING_METHOD_DETAILS"; + public static final String SHIPPING_METHOD_TITLE ="SHIPPING_METHOD_TITLE"; + public static final String ADDRESS_DELIVERY_TITLE ="ADDRESS_DELIVERY_TITLE"; + + public static final String EMAIL_CUSTOMER_CONTACT ="EMAIL_CUSTOMER_CONTACT"; + public static final String EMAIL_CONTACT_NAME_LABEL ="EMAIL_CONTACT_NAME_LABEL"; + public static final String EMAIL_CONTACT_NAME ="EMAIL_CONTACT_NAME"; + public static final String EMAIL_CONTACT_EMAIL_LABEL ="EMAIL_CONTACT_EMAIL_LABEL"; + public static final String EMAIL_CONTACT_EMAIL ="EMAIL_CONTACT_EMAIL"; + public static final String EMAIL_CONTACT_CONTENT ="EMAIL_CONTACT_CONTENT"; + + + + public final static String LABEL_HI = "LABEL_HI"; + public final static String CUSTOMER_ACCESS_LABEL = "CUSTOMER_ACCESS_LABEL"; + public final static String CUSTOMER_ACCESS_URL = "CUSTOMER_ACCESS_URL"; + public final static String ACCESS_NOW_LABEL = "ACCESS_NOW_LABEL"; + public final static String LABEL_LINK_TITLE = "LABEL_LINK_TITLE"; + public final static String LABEL_LINK = "LABEL_LINK"; + + public static final String EMAIL_CUSTOMER_TPL = "email_template_customer.ftl"; + public static final String EMAIL_ORDER_TPL = "email_template_checkout.ftl"; + public static final String EMAIL_ORDER_DOWNLOAD_TPL = "email_template_checkout_download.ftl"; + public static final String ORDER_STATUS_TMPL = "email_template_order_status.ftl"; + public static final String EMAIL_CONTACT_TMPL = "email_template_contact.ftl"; + public static final String EMAIL_NOTIFICATION_TMPL = "email_template_notification.ftl"; + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/controller/FilesController.java b/sm-shop/src/main/java/com/salesmanager/shop/controller/FilesController.java new file mode 100755 index 0000000000..e47af3ec43 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/controller/FilesController.java @@ -0,0 +1,92 @@ +package com.salesmanager.shop.controller; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.content.ContentService; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.OutputContentFile; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.store.controller.AbstractController; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@Controller +public class FilesController extends AbstractController { + + private static final Logger LOGGER = LoggerFactory.getLogger(FilesController.class); + + + + @Inject + private ContentService contentService; + + + /** + * Serves static files (css, js ...) the repository is a single node by merchant + * @param storeCode + * @param extension + * @return + * @throws IOException + * @throws ServiceException + */ + @RequestMapping("/static/files/{storeCode}/{fileName}.{extension}") + public @ResponseBody byte[] downloadFile(@PathVariable final String storeCode, @PathVariable final String fileName, @PathVariable final String extension, HttpServletRequest request, HttpServletResponse response) throws IOException, ServiceException { + + // example -> /files//myfile.css + FileContentType fileType = FileContentType.STATIC_FILE; + + // needs to query the new API + OutputContentFile file =contentService.getContentFile(storeCode, fileType, new StringBuilder().append(fileName).append(".").append(extension).toString()); + + + if(file!=null) { + return file.getFile().toByteArray(); + } else { + LOGGER.debug("File not found " + fileName + "." + extension); + response.sendError(404, Constants.FILE_NOT_FOUND); + return null; + } + } + + /** + * Requires admin with roles admin, superadmin or product + * @param storeCode + * @param fileName + * @param extension + * @param request + * @param response + * @return + * @throws Exception + */ + @PreAuthorize("hasRole('PRODUCTS')") + @RequestMapping("/admin/files/downloads/{storeCode}/{fileName}.{extension}") + public @ResponseBody byte[] downloadProduct(@PathVariable final String storeCode, @PathVariable final String fileName, @PathVariable final String extension, HttpServletRequest request, HttpServletResponse response) throws Exception { + + FileContentType fileType = FileContentType.PRODUCT_DIGITAL; + + String fileNameAndExtension = new StringBuilder().append(fileName).append(".").append(extension).toString(); + + // needs to query the new API + OutputContentFile file = contentService.getContentFile(storeCode, fileType, fileNameAndExtension); + + + if(file!=null) { + response.setHeader("Content-Disposition", "attachment; filename=\"" + fileNameAndExtension + "\""); + return file.getFile().toByteArray(); + } else { + LOGGER.debug("File not found " + fileName + "." + extension); + response.sendError(404, Constants.FILE_NOT_FOUND); + return null; + } + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/controller/ImagesController.java b/sm-shop/src/main/java/com/salesmanager/shop/controller/ImagesController.java new file mode 100755 index 0000000000..6331eb4b03 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/controller/ImagesController.java @@ -0,0 +1,256 @@ +package com.salesmanager.shop.controller; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.util.ResourceUtils; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.product.image.ProductImageService; +import com.salesmanager.core.business.services.content.ContentService; +import com.salesmanager.core.model.catalog.product.file.ProductImageSize; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.OutputContentFile; + +/** + * When handling images and files from the application server + * @author c.samson + * + */ +@Controller +public class ImagesController { + + private static final Logger LOGGER = LoggerFactory.getLogger(ImagesController.class); + + + + @Inject + private ContentService contentService; + + @Inject + private ProductImageService productImageService; + + private byte[] tempImage = null; + + @PostConstruct + public void init() { + try { + File file = ResourceUtils.getFile("classpath:static/not-found.png"); + if(file != null) { + byte[] bFile = Files.readAllBytes(file.toPath()); + this.tempImage = bFile; + } + + + } catch (Exception e) { + LOGGER.error("Can't load temporary default image", e); + } + } + + /** + * Logo, content image + * @param storeId + * @param imageType (LOGO, CONTENT, IMAGE) + * @param imageName + * @return + * @throws IOException + * @throws ServiceException + */ + @RequestMapping("/static/files/{storeCode}/{imageType}/{imageName}.{extension}") + public @ResponseBody byte[] printImage(@PathVariable final String storeCode, @PathVariable final String imageType, @PathVariable final String imageName, @PathVariable final String extension) throws IOException, ServiceException { + + // example -> /static/files/DEFAULT/CONTENT/myImage.png + + FileContentType imgType = null; + + if(FileContentType.LOGO.name().equals(imageType)) { + imgType = FileContentType.LOGO; + } + + if(FileContentType.IMAGE.name().equals(imageType)) { + imgType = FileContentType.IMAGE; + } + + if(FileContentType.PROPERTY.name().equals(imageType)) { + imgType = FileContentType.PROPERTY; + } + + OutputContentFile image =contentService.getContentFile(storeCode, imgType, new StringBuilder().append(imageName).append(".").append(extension).toString()); + + + if(image!=null) { + return image.getFile().toByteArray(); + } else { + return tempImage; + } + + } + + + /** + * For product images + * @Deprecated + * @param storeCode + * @param productCode + * @param imageType + * @param imageName + * @param extension + * @return + * @throws IOException + */ + @RequestMapping("/static/{storeCode}/{imageType}/{productCode}/{imageName}.{extension}") + public @ResponseBody byte[] printImage(@PathVariable final String storeCode, @PathVariable final String productCode, @PathVariable final String imageType, @PathVariable final String imageName, @PathVariable final String extension) throws IOException { + + // product image + // example small product image -> /static/DEFAULT/products/TB12345/product1.jpg + + // example large product image -> /static/DEFAULT/products/TB12345/product1.jpg + + + /** + * List of possible imageType + * + */ + + + ProductImageSize size = ProductImageSize.SMALL; + + if(imageType.equals(FileContentType.PRODUCTLG.name())) { + size = ProductImageSize.LARGE; + } + + + + OutputContentFile image = null; + try { + image = productImageService.getProductImage(storeCode, productCode, new StringBuilder().append(imageName).append(".").append(extension).toString(), size); + } catch (ServiceException e) { + LOGGER.error("Cannot retrieve image " + imageName, e); + } + if(image!=null) { + return image.getFile().toByteArray(); + } else { + //empty image placeholder + return tempImage; + } + + } + + /** + * Exclusive method for dealing with product images + * @param storeCode + * @param productCode + * @param imageName + * @param extension + * @param request + * @return + * @throws IOException + */ + @RequestMapping(value="/static/products/{storeCode}/{productCode}/{imageSize}/{imageName}.{extension}", + produces = {"image/gif", "image/jpg", "image/png", "application/octet-stream"}) + public @ResponseBody byte[] printImage(@PathVariable final String storeCode, @PathVariable final String productCode, @PathVariable final String imageSize, @PathVariable final String imageName, @PathVariable final String extension, HttpServletRequest request) throws IOException { + + // product image small + // example small product image -> /static/products/DEFAULT/TB12345/SMALL/product1.jpg + + // example large product image -> /static/products/DEFAULT/TB12345/LARGE/product1.jpg + + + /** + * List of possible imageType + * + */ + + + ProductImageSize size = ProductImageSize.SMALL; + + if(FileContentType.PRODUCTLG.name().equals(imageSize)) { + size = ProductImageSize.LARGE; + } + + + + + OutputContentFile image = null; + try { + image = productImageService.getProductImage(storeCode, productCode, new StringBuilder().append(imageName).append(".").append(extension).toString(), size); + } catch (ServiceException e) { + LOGGER.error("Cannot retrieve image " + imageName, e); + } + if(image!=null) { + return image.getFile().toByteArray(); + } else { + //empty image placeholder + return tempImage; + } + + } + + /** + * Exclusive method for dealing with product images + * @param storeCode + * @param productCode + * @param imageName + * @param extension + * @param request + * @return + * @throws IOException + */ + @RequestMapping(value="/static/products/{storeCode}/{productCode}/{imageName}.{extension}", + produces = {"image/gif", "image/jpg", "image/png", "application/octet-stream"}) + public @ResponseBody byte[] printImage(@PathVariable final String storeCode, @PathVariable final String productCode, @PathVariable final String imageName, @PathVariable final String extension, HttpServletRequest request) throws IOException { + + // product image + // example small product image -> /static/products/DEFAULT/TB12345/product1.jpg?size=small + + // example large product image -> /static/products/DEFAULT/TB12345/product1.jpg + // or + //example large product image -> /static/products/DEFAULT/TB12345/product1.jpg?size=large + + + /** + * List of possible imageType + * + */ + + + ProductImageSize size = ProductImageSize.LARGE; + + + if(StringUtils.isNotBlank(request.getParameter("size"))) { + String requestSize = request.getParameter("size"); + if(requestSize.equals(ProductImageSize.SMALL.name())) { + size = ProductImageSize.SMALL; + } + } + + + + OutputContentFile image = null; + try { + image = productImageService.getProductImage(storeCode, productCode, new StringBuilder().append(imageName).append(".").append(extension).toString(), size); + } catch (ServiceException e) { + LOGGER.error("Cannot retrieve image " + imageName, e); + } + if(image!=null) { + return image.getFile().toByteArray(); + } else { + //empty image placeholder + return tempImage; + } + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/filter/CorsFilter.java b/sm-shop/src/main/java/com/salesmanager/shop/filter/CorsFilter.java new file mode 100755 index 0000000000..379dfec32a --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/filter/CorsFilter.java @@ -0,0 +1,45 @@ +package com.salesmanager.shop.filter; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; + +public class CorsFilter extends HandlerInterceptorAdapter { + + public CorsFilter() { + + } + + /** + * Allows public web services to work from remote hosts + */ + public boolean preHandle( + HttpServletRequest request, + HttpServletResponse response, + Object handler) throws Exception { + + HttpServletResponse httpResponse = (HttpServletResponse) response; + + String origin = "*"; + if(!StringUtils.isBlank(request.getHeader("origin"))) { + origin = request.getHeader("origin"); + } + + httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH"); + httpResponse.setHeader("Access-Control-Allow-Headers", "X-Auth-Token, Content-Type, Authorization, Cache-Control, X-Requested-With"); + httpResponse.setHeader("Access-Control-Allow-Origin", origin); + + return true; + + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/filter/XssFilter.java b/sm-shop/src/main/java/com/salesmanager/shop/filter/XssFilter.java new file mode 100644 index 0000000000..042110f281 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/filter/XssFilter.java @@ -0,0 +1,49 @@ +package com.salesmanager.shop.filter; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + + +@Component +@Order(0) +public class XssFilter implements Filter { + + /** + * Description: Log + */ + private static final Logger LOGGER = LoggerFactory.getLogger(XssFilter.class); + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + LOGGER.debug("(XssFilter) initialize"); + } + + + @Override + public void doFilter(ServletRequest srequest, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { + + HttpServletRequest request = (HttpServletRequest) srequest; + filterChain.doFilter(new XssHttpServletRequestWrapper(request) {}, response); + + } + + + + @Override + public void destroy() { + LOGGER.debug("(XssFilter) destroy"); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/filter/XssHttpServletRequestWrapper.java b/sm-shop/src/main/java/com/salesmanager/shop/filter/XssHttpServletRequestWrapper.java new file mode 100644 index 0000000000..ccbf69a999 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/filter/XssHttpServletRequestWrapper.java @@ -0,0 +1,58 @@ +package com.salesmanager.shop.filter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; + +import com.salesmanager.shop.utils.SanitizeUtils; + +/** + * Cross Site Scripting filter enforcing html encoding of request parameters + * @author carlsamson + * + */ +public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { + + public XssHttpServletRequestWrapper(HttpServletRequest request) { + super(request); + + } + + + + @Override + public String getHeader(String name) { + String value = super.getHeader(name); + if (value == null) + return null; + return cleanXSS(value); + } + + + public String[] getParameterValues(String parameter) { + String[] values = super.getParameterValues(parameter); + if (values == null) { + return null; + } + int count = values.length; + String[] encodedValues = new String[count]; + for (int i = 0; i < count; i++) { + encodedValues[i] = cleanXSS(values[i]); + } + return encodedValues; + } + + @Override + public String getParameter(String parameter) { + String value = super.getParameter(parameter); + if (value == null) { + return null; + } + return cleanXSS(value); + } + + private String cleanXSS(String value) { + // You'll need to remove the spaces from the html entities below + return SanitizeUtils.getSafeString(value); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/init/data/InitData.java b/sm-shop/src/main/java/com/salesmanager/shop/init/data/InitData.java new file mode 100755 index 0000000000..2f03c6d6be --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/init/data/InitData.java @@ -0,0 +1,9 @@ +package com.salesmanager.shop.init.data; + +import com.salesmanager.core.business.exception.ServiceException; + +public interface InitData { + + public void initInitialData() throws ServiceException; + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/init/data/InitializationLoader.java b/sm-shop/src/main/java/com/salesmanager/shop/init/data/InitializationLoader.java new file mode 100755 index 0000000000..f670dbec0e --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/init/data/InitializationLoader.java @@ -0,0 +1,105 @@ +package com.salesmanager.shop.init.data; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.constants.SystemConstants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.merchant.MerchantStoreService; +import com.salesmanager.core.business.services.reference.init.InitializationDatabase; +import com.salesmanager.core.business.services.system.MerchantConfigurationService; +import com.salesmanager.core.business.services.system.SystemConfigurationService; +import com.salesmanager.core.business.services.user.GroupService; +import com.salesmanager.core.business.services.user.PermissionService; +import com.salesmanager.core.business.utils.CoreConfiguration; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.system.MerchantConfig; +import com.salesmanager.core.model.system.SystemConfiguration; +import com.salesmanager.shop.admin.security.WebUserServices; +import com.salesmanager.shop.constants.ApplicationConstants; + + +@Component +public class InitializationLoader { + + private static final Logger LOGGER = LoggerFactory.getLogger(InitializationLoader.class); + + @Value("${db.init.data:true}") + private boolean initDefaultData; + + + @Inject + private MerchantConfigurationService merchantConfigurationService; + + @Inject + private InitializationDatabase initializationDatabase; + + //@Inject + //private InitData initData; + + @Inject + private SystemConfigurationService systemConfigurationService; + + @Inject + private WebUserServices userDetailsService; + + @Inject + protected PermissionService permissionService; + + @Inject + protected GroupService groupService; + + @Inject + private CoreConfiguration configuration; + + @Inject + protected MerchantStoreService merchantService; + + + @PostConstruct + public void init() { + + try { + + //Check flag to populate or not the database + if(!this.initDefaultData) { + return; + } + + if (initializationDatabase.isEmpty()) { + + + //All default data to be created + + LOGGER.info(String.format("%s : Shopizer database is empty, populate it....", "sm-shop")); + + initializationDatabase.populate("sm-shop"); + + MerchantStore store = merchantService.getByCode(MerchantStore.DEFAULT_STORE); + + userDetailsService.createDefaultAdmin(); + MerchantConfig config = new MerchantConfig(); + config.setAllowPurchaseItems(true); + config.setDisplayAddToCartOnFeaturedItems(true); + + merchantConfigurationService.saveMerchantConfig(config, store); + + + } + + } catch (Exception e) { + LOGGER.error("Error in the init method",e); + } + + } + + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/Mapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/Mapper.java new file mode 100755 index 0000000000..62e43d08be --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/Mapper.java @@ -0,0 +1,12 @@ +package com.salesmanager.shop.mapper; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +public interface Mapper { + + T convert(S source, MerchantStore store, Language language); + T merge(S source, T destination, MerchantStore store, Language language); + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/cart/ReadableShoppingCartMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/cart/ReadableShoppingCartMapper.java new file mode 100644 index 0000000000..ba56548121 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/cart/ReadableShoppingCartMapper.java @@ -0,0 +1,303 @@ +package com.salesmanager.shop.mapper.cart; + +import java.math.BigDecimal; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService; +import com.salesmanager.core.business.services.catalog.product.variant.ProductVariantService; +import com.salesmanager.core.business.services.shoppingcart.ShoppingCartCalculationService; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValueDescription; +import com.salesmanager.core.model.catalog.product.variant.ProductVariantImage; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.OrderSummary; +import com.salesmanager.core.model.order.OrderTotalSummary; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.mapper.catalog.ReadableMinimalProductMapper; +import com.salesmanager.shop.mapper.catalog.ReadableProductVariationMapper; +import com.salesmanager.shop.model.catalog.product.ReadableImage; +import com.salesmanager.shop.model.order.total.ReadableOrderTotal; +import com.salesmanager.shop.model.shoppingcart.ReadableShoppingCart; +import com.salesmanager.shop.model.shoppingcart.ReadableShoppingCartAttribute; +import com.salesmanager.shop.model.shoppingcart.ReadableShoppingCartAttributeOption; +import com.salesmanager.shop.model.shoppingcart.ReadableShoppingCartAttributeOptionValue; +import com.salesmanager.shop.model.shoppingcart.ReadableShoppingCartItem; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.utils.ImageFilePath; + +@Component +public class ReadableShoppingCartMapper implements Mapper { + + private static final Logger LOG = LoggerFactory.getLogger(ReadableShoppingCartMapper.class); + + @Autowired + private ShoppingCartCalculationService shoppingCartCalculationService; + + @Autowired + private PricingService pricingService; + + @Autowired + private ProductAttributeService productAttributeService; + + @Autowired + private ProductVariantService productVariantService; + + @Autowired + private ReadableMinimalProductMapper readableMinimalProductMapper; + + @Autowired + private ReadableProductVariationMapper readableProductVariationMapper; + + @Autowired + @Qualifier("img") + private ImageFilePath imageUtils; + + @Override + public ReadableShoppingCart convert(ShoppingCart source, MerchantStore store, Language language) { + ReadableShoppingCart destination = new ReadableShoppingCart(); + return this.merge(source, destination, store, language); + } + + private ReadableImage image(ProductVariantImage instanceImage, MerchantStore store, Language language) { + ReadableImage img = new ReadableImage(); + img.setDefaultImage(instanceImage.isDefaultImage()); + img.setId(instanceImage.getId()); + img.setImageName(instanceImage.getProductImage()); + img.setImageUrl(imageUtils.buildCustomTypeImageUtils(store, img.getImageName(), FileContentType.VARIANT)); + return img; + } + + @Override + public ReadableShoppingCart merge(ShoppingCart source, ReadableShoppingCart destination, MerchantStore store, + Language language) { + Validate.notNull(source, "ShoppingCart cannot be null"); + Validate.notNull(destination, "ReadableShoppingCart cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + + destination.setCode(source.getShoppingCartCode()); + int cartQuantity = 0; + + destination.setCustomer(source.getCustomerId()); + + try { + + if (!StringUtils.isBlank(source.getPromoCode())) { + Date promoDateAdded = source.getPromoAdded();// promo valid 1 day + if (promoDateAdded == null) { + promoDateAdded = new Date(); + } + Instant instant = promoDateAdded.toInstant(); + ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault()); + LocalDate date = zdt.toLocalDate(); + // date added < date + 1 day + LocalDate tomorrow = LocalDate.now().plusDays(1); + if (date.isBefore(tomorrow)) { + destination.setPromoCode(source.getPromoCode()); + } + } + + Set items = source.getLineItems(); + + if (items != null) { + + for (com.salesmanager.core.model.shoppingcart.ShoppingCartItem item : items) { + ReadableShoppingCartItem shoppingCartItem = new ReadableShoppingCartItem(); + readableMinimalProductMapper.merge(item.getProduct(), shoppingCartItem, store, language); + + //variation + if(item.getVariant() != null) { + Optional productVariant = productVariantService.getById(item.getVariant(), store); + if(productVariant.isEmpty()) { + throw new ConversionRuntimeException("An error occured during shopping cart [" + source.getShoppingCartCode() + "] conversion, productVariant [" + item.getVariant() + "] not found"); + } + shoppingCartItem.setVariant(readableProductVariationMapper.convert(productVariant.get().getVariation(), store, language)); + if(productVariant.get().getVariationValue() != null) { + shoppingCartItem.setVariantValue(readableProductVariationMapper.convert(productVariant.get().getVariationValue(), store, language)); + } + + if(productVariant.get().getProductVariantGroup() != null) { + Set nameSet = new HashSet<>(); + List instanceImages = productVariant.get().getProductVariantGroup().getImages() + .stream().map(i -> this.image(i, store, language)) + .filter(e -> nameSet.add(e.getImageUrl())) + .collect(Collectors.toList()); + shoppingCartItem.setImages(instanceImages); + } + } + + + + + shoppingCartItem.setPrice(item.getItemPrice()); + shoppingCartItem.setFinalPrice(pricingService.getDisplayAmount(item.getItemPrice(), store)); + + shoppingCartItem.setQuantity(item.getQuantity()); + + cartQuantity = cartQuantity + item.getQuantity(); + + BigDecimal subTotal = pricingService.calculatePriceQuantity(item.getItemPrice(), + item.getQuantity()); + + // calculate sub total (price * quantity) + shoppingCartItem.setSubTotal(subTotal); + + shoppingCartItem.setDisplaySubTotal(pricingService.getDisplayAmount(subTotal, store)); + + Set attributes = item + .getAttributes(); + if (attributes != null) { + for (com.salesmanager.core.model.shoppingcart.ShoppingCartAttributeItem attribute : attributes) { + + ProductAttribute productAttribute = productAttributeService + .getById(attribute.getProductAttributeId()); + + if (productAttribute == null) { + LOG.warn("Product attribute with ID " + attribute.getId() + + " not found, skipping cart attribute " + attribute.getId()); + continue; + } + + ReadableShoppingCartAttribute cartAttribute = new ReadableShoppingCartAttribute(); + + cartAttribute.setId(attribute.getId()); + + ProductOption option = productAttribute.getProductOption(); + ProductOptionValue optionValue = productAttribute.getProductOptionValue(); + + List optionDescriptions = option.getDescriptionsSettoList(); + List optionValueDescriptions = optionValue + .getDescriptionsSettoList(); + + String optName = null; + String optValue = null; + if (!CollectionUtils.isEmpty(optionDescriptions) + && !CollectionUtils.isEmpty(optionValueDescriptions)) { + + optName = optionDescriptions.get(0).getName(); + optValue = optionValueDescriptions.get(0).getName(); + + for (ProductOptionDescription optionDescription : optionDescriptions) { + if (optionDescription.getLanguage() != null && optionDescription.getLanguage() + .getId().intValue() == language.getId().intValue()) { + optName = optionDescription.getName(); + break; + } + } + + for (ProductOptionValueDescription optionValueDescription : optionValueDescriptions) { + if (optionValueDescription.getLanguage() != null && optionValueDescription + .getLanguage().getId().intValue() == language.getId().intValue()) { + optValue = optionValueDescription.getName(); + break; + } + } + + } + + if (optName != null) { + ReadableShoppingCartAttributeOption attributeOption = new ReadableShoppingCartAttributeOption(); + attributeOption.setCode(option.getCode()); + attributeOption.setId(option.getId()); + attributeOption.setName(optName); + cartAttribute.setOption(attributeOption); + } + + if (optValue != null) { + ReadableShoppingCartAttributeOptionValue attributeOptionValue = new ReadableShoppingCartAttributeOptionValue(); + attributeOptionValue.setCode(optionValue.getCode()); + attributeOptionValue.setId(optionValue.getId()); + attributeOptionValue.setName(optValue); + cartAttribute.setOptionValue(attributeOptionValue); + } + shoppingCartItem.getCartItemattributes().add(cartAttribute); + } + + } + destination.getProducts().add(shoppingCartItem); + } + } + + // Calculate totals using shoppingCartService + // OrderSummary contains ShoppingCart items + + OrderSummary summary = new OrderSummary(); + List productsList = new ArrayList(); + productsList.addAll(source.getLineItems()); + summary.setProducts(productsList); + + // OrdetTotalSummary contains all calculations + + OrderTotalSummary orderSummary = shoppingCartCalculationService.calculate(source, store, language); + + if (CollectionUtils.isNotEmpty(orderSummary.getTotals())) { + + if (orderSummary.getTotals().stream() + .filter(t -> Constants.OT_DISCOUNT_TITLE.equals(t.getOrderTotalCode())).count() == 0) { + // no promo coupon applied + destination.setPromoCode(null); + + } + + List totals = new ArrayList(); + for (com.salesmanager.core.model.order.OrderTotal t : orderSummary.getTotals()) { + ReadableOrderTotal total = new ReadableOrderTotal(); + total.setCode(t.getOrderTotalCode()); + total.setValue(t.getValue()); + total.setText(t.getText()); + totals.add(total); + } + destination.setTotals(totals); + } + + destination.setSubtotal(orderSummary.getSubTotal()); + destination.setDisplaySubTotal(pricingService.getDisplayAmount(orderSummary.getSubTotal(), store)); + + destination.setTotal(orderSummary.getTotal()); + destination.setDisplayTotal(pricingService.getDisplayAmount(orderSummary.getTotal(), store)); + + destination.setQuantity(cartQuantity); + destination.setId(source.getId()); + + if (source.getOrderId() != null) { + destination.setOrder(source.getOrderId()); + } + + } catch (Exception e) { + throw new ConversionRuntimeException("An error occured while converting ReadableShoppingCart", e); + } + + return destination; + } + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableCatalogCategoryEntryMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableCatalogCategoryEntryMapper.java new file mode 100644 index 0000000000..109d21354a --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableCatalogCategoryEntryMapper.java @@ -0,0 +1,86 @@ +package com.salesmanager.shop.mapper.catalog; + +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.catalog.catalog.Catalog; +import com.salesmanager.core.model.catalog.catalog.CatalogCategoryEntry; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.catalog.PersistableCatalogCategoryEntry; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.store.controller.catalog.facade.CatalogFacade; +import com.salesmanager.shop.store.controller.category.facade.CategoryFacade; + +@Component +public class PersistableCatalogCategoryEntryMapper implements Mapper { + + + @Autowired + private CategoryFacade categoryFacade; + + @Autowired + private CatalogFacade catalogFacade; + + + @Override + public CatalogCategoryEntry convert(PersistableCatalogCategoryEntry source, MerchantStore store, Language language) { + CatalogCategoryEntry destination = new CatalogCategoryEntry(); + return this.merge(source, destination, store, language); + } + + @Override + public CatalogCategoryEntry merge(PersistableCatalogCategoryEntry source, CatalogCategoryEntry destination, MerchantStore store, + Language language) { + Validate.notNull(source, "CatalogEntry must not be null"); + Validate.notNull(store, "MerchantStore must not be null"); + Validate.notNull(source.getProductCode(), "ProductCode must not be null"); + Validate.notNull(source.getCategoryCode(), "CategoryCode must not be null"); + Validate.notNull(source.getCatalog(), "Catalog must not be null"); + + + + if(destination == null) { + destination = new CatalogCategoryEntry(); + + } + destination.setId(source.getId()); + destination.setVisible(source.isVisible()); + + + try { + + String catalog = source.getCatalog(); + + Catalog catalogModel = catalogFacade.getCatalog(catalog, store); + if(catalogModel == null) { + throw new ConversionRuntimeException("Error while converting CatalogEntry product [" + source.getCatalog() + "] not found"); + } + + destination.setCatalog(catalogModel); + +/* Product productModel = productFacade.getProduct(source.getProductCode(), store); + if(productModel == null) { + throw new ConversionRuntimeException("Error while converting CatalogEntry product [" + source.getProductCode() + "] not found"); + }*/ + + //destination.setProduct(productModel); + + Category categoryModel = categoryFacade.getByCode(source.getCategoryCode(), store); + if(categoryModel == null) { + throw new ConversionRuntimeException("Error while converting CatalogEntry category [" + source.getCategoryCode() + "] not found"); + } + + destination.setCategory(categoryModel); + + } catch (Exception e) { + throw new ConversionRuntimeException("Error while converting CatalogEntry", e); + } + + return destination; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableCatalogMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableCatalogMapper.java new file mode 100644 index 0000000000..934744178f --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableCatalogMapper.java @@ -0,0 +1,33 @@ +package com.salesmanager.shop.mapper.catalog; + +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.catalog.catalog.Catalog; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.catalog.PersistableCatalog; + +@Component +public class PersistableCatalogMapper implements Mapper { + + @Override + public Catalog convert(PersistableCatalog source, MerchantStore store, Language language) { + Catalog c = new Catalog(); + return this.merge(source, c, store, language); + } + + @Override + public Catalog merge(PersistableCatalog source, Catalog destination, MerchantStore store, Language language) { + + + destination.setCode(source.getCode()); + destination.setDefaultCatalog(source.isDefaultCatalog()); + destination.setId(source.getId()); + destination.setMerchantStore(store); + destination.setVisible(source.isVisible()); + + return destination; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductAttributeMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductAttributeMapper.java new file mode 100644 index 0000000000..3e6740d57d --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductAttributeMapper.java @@ -0,0 +1,136 @@ +package com.salesmanager.shop.mapper.catalog; + +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductOptionService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductOptionValueService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductAttribute; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductOptionValue; +import com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; + +@Component +public class PersistableProductAttributeMapper implements Mapper { + + @Inject + private ProductOptionService productOptionService; + @Inject + private ProductOptionValueService productOptionValueService; + @Inject + private ProductService productService; + @Inject + private PersistableProductOptionValueMapper persistableProductOptionValueMapper; + + @Override + public ProductAttribute convert(PersistableProductAttribute source, MerchantStore store, Language language) { + ProductAttribute attribute = new ProductAttribute(); + return merge(source,attribute,store,language); + } + + @Override + public ProductAttribute merge(PersistableProductAttribute source, ProductAttribute destination, + MerchantStore store, Language language) { + + + ProductOption productOption = null; + + if(!StringUtils.isBlank(source.getOption().getCode())) { + productOption = productOptionService.getByCode(store, source.getOption().getCode()); + } else { + Validate.notNull(source.getOption().getId(),"Product option id is null"); + productOption = productOptionService.getById(source.getOption().getId()); + } + + if(productOption==null) { + throw new ConversionRuntimeException("Product option id " + source.getOption().getId() + " does not exist"); + } + + ProductOptionValue productOptionValue = null; + + if(!StringUtils.isBlank(source.getOptionValue().getCode())) { + productOptionValue = productOptionValueService.getByCode(store, source.getOptionValue().getCode()); + } else if(source.getProductId() != null && source.getOptionValue().getId().longValue()>0) { + productOptionValue = productOptionValueService.getById(source.getOptionValue().getId()); + } else { + //ProductOption value is text + productOptionValue = new ProductOptionValue(); + productOptionValue.setProductOptionDisplayOnly(true); + productOptionValue.setCode(UUID.randomUUID().toString()); + productOptionValue.setMerchantStore(store); + } + + if(!CollectionUtils.isEmpty((source.getOptionValue().getDescriptions()))) { + productOptionValue = persistableProductOptionValueMapper.merge(source.getOptionValue(),productOptionValue, store, language); + try { + productOptionValueService.saveOrUpdate(productOptionValue); + } catch (ServiceException e) { + throw new ConversionRuntimeException("Error converting ProductOptionValue",e); + } + } + + if(productOptionValue==null && ! source.isAttributeDisplayOnly()) { + throw new ConversionRuntimeException("Product option value id " + source.getOptionValue().getId() + " does not exist"); + } + + + + /** + productOptionValue + .getDescriptions().stream() + .map(val -> this.persistableProductOptionValueMapper.convert(val, store, language)).collect(Collectors.toList()); + + }**/ + + if(productOption.getMerchantStore().getId().intValue()!=store.getId().intValue()) { + throw new ConversionRuntimeException("Invalid product option id "); + } + + if(productOptionValue!=null && productOptionValue.getMerchantStore().getId().intValue()!=store.getId().intValue()) { + throw new ConversionRuntimeException("Invalid product option value id "); + } + + if(source.getProductId() != null && source.getProductId().longValue() >0 ) { + Product p = productService.getById(source.getProductId()); + if(p == null) { + throw new ConversionRuntimeException("Invalid product id "); + } + destination.setProduct(p); + } + + + if(destination.getId()!=null && destination.getId().longValue()>0) { + destination.setId(destination.getId()); + } else { + destination.setId(null); + } + + destination.setProductOption(productOption); + destination.setProductOptionValue(productOptionValue); + destination.setProductAttributePrice(source.getProductAttributePrice()); + destination.setProductAttributeWeight(source.getProductAttributeWeight()); + destination.setProductAttributePrice(source.getProductAttributePrice()); + destination.setAttributeDisplayOnly(source.isAttributeDisplayOnly()); + + + return destination; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductOptionMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductOptionMapper.java new file mode 100644 index 0000000000..085c95eb48 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductOptionMapper.java @@ -0,0 +1,92 @@ +package com.salesmanager.shop.mapper.catalog; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.attribute.api.PersistableProductOptionEntity; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; + +@Component +public class PersistableProductOptionMapper implements Mapper { + + @Autowired + private LanguageService languageService; + + + + ProductOptionDescription description(com.salesmanager.shop.model.catalog.product.attribute.ProductOptionDescription description) throws Exception { + Validate.notNull(description.getLanguage(),"description.language should not be null"); + ProductOptionDescription desc = new ProductOptionDescription(); + desc.setId(null); + desc.setDescription(description.getDescription()); + desc.setName(description.getName()); + if(description.getId() != null && description.getId().longValue()>0) { + desc.setId(description.getId()); + } + Language lang = languageService.getByCode(description.getLanguage()); + desc.setLanguage(lang); + return desc; + } + + + @Override + public ProductOption convert(PersistableProductOptionEntity source, MerchantStore store, + Language language) { + ProductOption destination = new ProductOption(); + return merge(source, destination, store, language); + } + + + @Override + public ProductOption merge(PersistableProductOptionEntity source, ProductOption destination, + MerchantStore store, Language language) { + if(destination == null) { + destination = new ProductOption(); + } + + try { + + if(!CollectionUtils.isEmpty(source.getDescriptions())) { + for(com.salesmanager.shop.model.catalog.product.attribute.ProductOptionDescription desc : source.getDescriptions()) { + ProductOptionDescription description = null; + if(!CollectionUtils.isEmpty(destination.getDescriptions())) { + for(ProductOptionDescription d : destination.getDescriptions()) { + if(!StringUtils.isBlank(desc.getLanguage()) && desc.getLanguage().equals(d.getLanguage().getCode())) { + d.setDescription(desc.getDescription()); + d.setName(desc.getName()); + d.setTitle(desc.getTitle()); + description = d; + break; + } + } + } + if(description == null) { + description = description(desc); + description.setProductOption(destination); + destination.getDescriptions().add(description); + } + } + } + + destination.setCode(source.getCode()); + destination.setMerchantStore(store); + destination.setProductOptionSortOrder(source.getOrder()); + destination.setProductOptionType(source.getType()); + destination.setReadOnly(source.isReadOnly()); + + + return destination; + } catch (Exception e) { + throw new ServiceRuntimeException("Error while converting product option", e); + } + } + +} \ No newline at end of file diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductOptionSetMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductOptionSetMapper.java new file mode 100644 index 0000000000..f28a711fe1 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductOptionSetMapper.java @@ -0,0 +1,82 @@ +package com.salesmanager.shop.mapper.catalog; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductOptionService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductOptionValueService; +import com.salesmanager.core.business.services.catalog.product.type.ProductTypeService; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionSet; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.attribute.optionset.PersistableProductOptionSet; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; + +@Component +public class PersistableProductOptionSetMapper implements Mapper { + + @Autowired + private ProductOptionService productOptionService; + + @Autowired + private ProductOptionValueService productOptionValueService; + + @Autowired + private ProductTypeService productTypeService; + + @Override + public ProductOptionSet convert(PersistableProductOptionSet source, MerchantStore store, Language language) { + + + ProductOptionSet optionSet = new ProductOptionSet(); + return this.merge(source, optionSet, store, language); + + } + + private ProductOptionValue value(Long productOptionValue, MerchantStore store) { + return productOptionValueService.getById(store, productOptionValue); + } + + @Override + public ProductOptionSet merge(PersistableProductOptionSet source, ProductOptionSet destination, + MerchantStore store, Language language) { + Validate.notNull(destination, "ProductOptionSet must not be null"); + + destination.setId(source.getId()); + destination.setCode(source.getCode()); + destination.setOptionDisplayOnly(source.isReadOnly()); + + ProductOption option = productOptionService.getById(store, source.getOption()); + destination.setOption(option); + + if(!CollectionUtils.isEmpty(source.getOptionValues())) { + List values = source.getOptionValues().stream().map(id -> value(id, store)).collect(Collectors.toList()); + destination.setValues(values); + } + + if(!CollectionUtils.isEmpty(source.getProductTypes())) { + try { + List types = productTypeService.listProductTypes(source.getProductTypes(), store, language); + Set typesSet = new HashSet(types); + destination.setProductTypes(typesSet); + } catch (ServiceException e) { + throw new ConversionRuntimeException("Error while mpping ProductOptionSet", e); + } + } + + return destination; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductOptionValueMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductOptionValueMapper.java new file mode 100644 index 0000000000..0cf8ae097e --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductOptionValueMapper.java @@ -0,0 +1,112 @@ +package com.salesmanager.shop.mapper.catalog; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValueDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductOptionValue; +import com.salesmanager.shop.model.catalog.product.attribute.api.PersistableProductOptionValueEntity; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; + +@Component +public class PersistableProductOptionValueMapper + implements Mapper { + + @Autowired + private LanguageService languageService; + + ProductOptionValueDescription description( + com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription description) + throws Exception { + Validate.notNull(description.getLanguage(), "description.language should not be null"); + ProductOptionValueDescription desc = new ProductOptionValueDescription(); + desc.setId(null); + desc.setDescription(description.getDescription()); + desc.setName(description.getName()); + if(StringUtils.isBlank(desc.getName())) { + desc.setName(description.getDescription()); + } + if (description.getId() != null && description.getId().longValue() > 0) { + desc.setId(description.getId()); + } + Language lang = languageService.getByCode(description.getLanguage()); + desc.setLanguage(lang); + return desc; + } + + @Override + public ProductOptionValue merge(PersistableProductOptionValue source, ProductOptionValue destination, + MerchantStore store, Language language) { + if (destination == null) { + destination = new ProductOptionValue(); + } + + try { + + if(StringUtils.isBlank(source.getCode())) { + if(!StringUtils.isBlank(destination.getCode())) { + source.setCode(destination.getCode()); + } + } + + if (!CollectionUtils.isEmpty(source.getDescriptions())) { + for (com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription desc : source + .getDescriptions()) { + ProductOptionValueDescription description = null; + if (!CollectionUtils.isEmpty(destination.getDescriptions())) { + for (ProductOptionValueDescription d : destination.getDescriptions()) { + if (!StringUtils.isBlank(desc.getLanguage()) + && desc.getLanguage().equals(d.getLanguage().getCode())) { + + d.setDescription(desc.getDescription()); + d.setName(desc.getName()); + d.setTitle(desc.getTitle()); + if(StringUtils.isBlank(d.getName())) { + d.setName(d.getDescription()); + } + description = d; + break; + + } + } + } //else { + if(description == null) { + description = description(desc); + description.setProductOptionValue(destination); + destination.getDescriptions().add(description); + } + //description = description(desc); + //description.setProductOptionValue(destination); + //} + //destination.getDescriptions().add(description); + } + } + + destination.setCode(source.getCode()); + destination.setMerchantStore(store); + destination.setProductOptionValueSortOrder(source.getSortOrder()); + + + return destination; + } catch (Exception e) { + throw new ServiceRuntimeException("Error while converting product option", e); + } + } + + @Override + public ProductOptionValue convert(PersistableProductOptionValue source, MerchantStore store, + Language language) { + ProductOptionValue destination = new ProductOptionValue(); + return merge(source, destination, store, language); + } + + +} \ No newline at end of file diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductTypeMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductTypeMapper.java new file mode 100644 index 0000000000..d49daf6121 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductTypeMapper.java @@ -0,0 +1,100 @@ +package com.salesmanager.shop.mapper.catalog; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.type.PersistableProductType; +import com.salesmanager.shop.model.catalog.product.type.ProductTypeDescription; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; + + +@Component +public class PersistableProductTypeMapper implements Mapper { + + @Autowired + private LanguageService languageService; + + @Override + public ProductType convert(PersistableProductType source, MerchantStore store, Language language) { + ProductType type = new ProductType(); + return this.merge(source, type, store, language); + } + + @Override + public ProductType merge(PersistableProductType source, ProductType destination, MerchantStore store, + Language language) { + Validate.notNull(destination, "ReadableProductType cannot be null"); + try { + return type(source, destination); + } catch (ServiceException e) { + throw new ConversionRuntimeException(e); + } + } + + private ProductType type (PersistableProductType type, ProductType destination) throws ServiceException { + if(destination == null) { + destination = new ProductType(); + } + destination.setCode(type.getCode()); + destination.setId(type.getId()); + destination.setAllowAddToCart(type.isAllowAddToCart()); + destination.setVisible(type.isVisible()); + //destination.set + + List descriptions = new ArrayList(); + if(!CollectionUtils.isEmpty(type.getDescriptions())) { + + for(ProductTypeDescription d : type.getDescriptions()) { + com.salesmanager.core.model.catalog.product.type.ProductTypeDescription desc = typeDescription(d, destination, d.getLanguage()); + descriptions.add(desc); + + + } + + destination.setDescriptions(new HashSet(descriptions)); + + } + + return destination; + } + + private com.salesmanager.core.model.catalog.product.type.ProductTypeDescription typeDescription(ProductTypeDescription description, ProductType typeModel, String lang) throws ServiceException { + + com.salesmanager.core.model.catalog.product.type.ProductTypeDescription desc = null; + if(!CollectionUtils.isEmpty(typeModel.getDescriptions()) ){ + desc = this.findAppropriateDescription(typeModel, lang); + } + + if(desc == null) { + desc = new com.salesmanager.core.model.catalog.product.type.ProductTypeDescription(); + } + + desc.setName(description.getName()); + desc.setDescription(description.getDescription()); + desc.setLanguage(languageService.getByCode(description.getLanguage())); + desc.setProductType(typeModel); + return desc; + } + + private com.salesmanager.core.model.catalog.product.type.ProductTypeDescription findAppropriateDescription(ProductType typeModel, String lang) { + java.util.Optional d = typeModel.getDescriptions().stream().filter(t -> t.getLanguage().getCode().equals(lang)).findFirst(); + if(d.isPresent()) { + return d.get(); + } else { + return null; + } + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductVariationMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductVariationMapper.java new file mode 100644 index 0000000000..3da5dc6df8 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/PersistableProductVariationMapper.java @@ -0,0 +1,62 @@ +package com.salesmanager.shop.mapper.catalog; + +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.services.catalog.product.attribute.ProductOptionService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductOptionValueService; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.catalog.product.variation.ProductVariation; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.variation.PersistableProductVariation; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; + +@Component +public class PersistableProductVariationMapper implements Mapper { + + @Autowired + private ProductOptionService productOptionService; + + @Autowired + private ProductOptionValueService productOptionValueService; + + @Override + public ProductVariation convert(PersistableProductVariation source, MerchantStore store, Language language) { + + ProductVariation variation = new ProductVariation(); + return this.merge(source, variation, store, language); + + } + + @Override + public ProductVariation merge(PersistableProductVariation source, ProductVariation destination, MerchantStore store, + Language language) { + Validate.notNull(destination, "ProductVariation cannot be null"); + + destination.setId(source.getId()); + destination.setCode(source.getCode()); + destination.setMerchantStore(store); + + ProductOption option = productOptionService.getById(store, source.getOption()); + if(option == null) { + throw new ConversionRuntimeException("ProductOption [" + source.getOption() + "] does not exists"); + } + destination.setProductOption(option); + + ProductOptionValue optionValue = productOptionValueService.getById(store, source.getOptionValue()); + if(optionValue == null) { + throw new ConversionRuntimeException("ProductOptionValue [" + source.getOptionValue() + "] does not exists"); + } + destination.setProductOptionValue(optionValue); + + + return destination; + + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableCatalogCategoryEntryMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableCatalogCategoryEntryMapper.java new file mode 100644 index 0000000000..fb3ab2be4e --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableCatalogCategoryEntryMapper.java @@ -0,0 +1,60 @@ +package com.salesmanager.shop.mapper.catalog; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.catalog.catalog.CatalogCategoryEntry; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.catalog.ReadableCatalogCategoryEntry; +import com.salesmanager.shop.model.catalog.category.ReadableCategory; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.utils.ImageFilePath; + +import java.util.Optional; + +@Component +public class ReadableCatalogCategoryEntryMapper implements Mapper { + + + @Autowired + private ReadableCategoryMapper readableCategoryMapper; + + @Autowired + @Qualifier("img") + private ImageFilePath imageUtils; + + @Override + public ReadableCatalogCategoryEntry convert(CatalogCategoryEntry source, MerchantStore store, Language language) { + ReadableCatalogCategoryEntry destination = new ReadableCatalogCategoryEntry(); + return merge(source, destination, store, language); + } + + @Override + public ReadableCatalogCategoryEntry merge(CatalogCategoryEntry source, ReadableCatalogCategoryEntry destination, MerchantStore store, + Language language) { + ReadableCatalogCategoryEntry convertedDestination = Optional.ofNullable(destination) + .orElse(new ReadableCatalogCategoryEntry()); + + try { + //ReadableProductPopulator readableProductPopulator = new ReadableProductPopulator(); + //readableProductPopulator.setimageUtils(imageUtils); + //readableProductPopulator.setPricingService(pricingService); + + //ReadableProduct readableProduct = readableProductPopulator.populate(source.getProduct(), store, language); + ReadableCategory readableCategory = readableCategoryMapper.convert(source.getCategory(), store, language); + + convertedDestination.setCatalog(source.getCatalog().getCode()); + + convertedDestination.setId(source.getId()); + convertedDestination.setVisible(source.isVisible()); + convertedDestination.setCategory(readableCategory); + //destination.setProduct(readableProduct); + return convertedDestination; + } catch (Exception e) { + throw new ConversionRuntimeException("Error while creating ReadableCatalogEntry", e); + } + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableCatalogMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableCatalogMapper.java new file mode 100644 index 0000000000..4a9e67304d --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableCatalogMapper.java @@ -0,0 +1,137 @@ +package com.salesmanager.shop.mapper.catalog; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.catalog.catalog.Catalog; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.catalog.ReadableCatalog; +import com.salesmanager.shop.model.catalog.category.ReadableCategory; +import com.salesmanager.shop.model.store.ReadableMerchantStore; +import com.salesmanager.shop.store.controller.store.facade.StoreFacade; +import com.salesmanager.shop.utils.DateUtil; + +@Component +public class ReadableCatalogMapper implements Mapper { + + @Autowired + private StoreFacade storeFacade; + + + @Autowired + private ReadableCategoryMapper readableCategoryMapper; + + @Override + public ReadableCatalog convert(Catalog source, MerchantStore store, Language language) { + ReadableCatalog destination = new ReadableCatalog(); + return merge(source, destination, store, language); + } + + @Override + public ReadableCatalog merge(Catalog source, ReadableCatalog destination, MerchantStore store, + Language language) { + if(destination == null) { + destination = new ReadableCatalog(); + } + + if(isPositive(source.getId())) { + destination.setId(source.getId()); + } + + destination.setCode(source.getCode()); + destination.setDefaultCatalog(source.isDefaultCatalog()); + destination.setVisible(source.isVisible()); + + Optional readableStore = Optional.ofNullable(source.getMerchantStore()) + .map(MerchantStore::getCode) + .map(code -> storeFacade.getByCode(code, language)); + readableStore.ifPresent(destination::setStore); + + destination.setDefaultCatalog(source.isDefaultCatalog()); + + Optional formattedCreationDate = Optional.ofNullable(source.getAuditSection()) + .map(AuditSection::getDateCreated) + .map(DateUtil::formatDate); + formattedCreationDate.ifPresent(destination::setCreationDate); + + if(CollectionUtils.isNotEmpty(source.getEntry())) { + + //hierarchy temp object + Map hierarchy = new HashMap(); + + source.getEntry().forEach(entry -> { + processCategory(entry.getCategory(), store, language, hierarchy, new HashMap<>()); + }); + + destination.setCategory(new ArrayList<>(hierarchy.values())); + } + + return destination; + + } + + private boolean isPositive(Long id) { + return Objects.nonNull(id) && id > 0; + } + + /** + * B + * 1 + * D + * 2 + * C + * 1 + * 4 + * A + * @param parent + * @param c + * @param store + * @param language + * @param hierarchy + */ + + //TODO it needs to cover by unit tests + private void processCategory(Category c, MerchantStore store, Language language, Map hierarchy, Map processed ) { + + //build category hierarchy + + ReadableCategory rc = null; + ReadableCategory rp = null; + + if(CollectionUtils.isNotEmpty(c.getCategories())) { + c.getCategories().stream().forEach(element -> { + processCategory(element, store, language, hierarchy, processed); + }); + } + + Category parent = c.getParent(); + if(Objects.nonNull(parent)) { + rp = hierarchy.computeIfAbsent(parent.getId(), i -> toReadableCategory(c.getParent(), store, language, processed)); + } + + rc = toReadableCategory(c, store, language, processed); + if(Objects.nonNull(rp)) { + rp.getChildren().add(rc); + } else { + hierarchy.put(c.getId(), rc); + } + + } + + private ReadableCategory toReadableCategory(Category c, MerchantStore store, Language lang, Map processed) { + Long id = c.getId(); + return processed.computeIfAbsent(id, it -> readableCategoryMapper.convert(c, store, lang)); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableCategoryMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableCategoryMapper.java new file mode 100755 index 0000000000..05350e5087 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableCategoryMapper.java @@ -0,0 +1,95 @@ +package com.salesmanager.shop.mapper.catalog; + +import java.util.*; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.category.CategoryDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.category.ReadableCategory; +import com.salesmanager.shop.model.catalog.category.ReadableCategoryFull; + +@Component +public class ReadableCategoryMapper implements Mapper { + + private static final Logger LOGGER = LoggerFactory.getLogger(ReadableCategoryMapper.class); + + @Override + public ReadableCategory convert(Category source, MerchantStore store, Language language) { + + if (Objects.isNull(language)) { + ReadableCategoryFull target = new ReadableCategoryFull(); + List descriptions = source.getDescriptions().stream() + .map(this::convertDescription) + .collect(Collectors.toList()); + target.setDescriptions(descriptions); + fillReadableCategory(target, source); + return target; + } else { + ReadableCategory target = new ReadableCategory(); + Optional description = source.getDescriptions().stream() + .filter(d -> language.getId().equals(d.getLanguage().getId())) + .map(this::convertDescription) + .findAny(); + description.ifPresent(target::setDescription); + fillReadableCategory(target, source); + return target; + } + } + + private void fillReadableCategory(ReadableCategory target, Category source) { + Optional parentCategory = + createParentCategory(source); + parentCategory.ifPresent(target::setParent); + + Optional.ofNullable(source.getDepth()).ifPresent(target::setDepth); + + target.setLineage(source.getLineage()); + target.setStore(source.getMerchantStore().getCode()); + target.setCode(source.getCode()); + target.setId(source.getId()); + target.setSortOrder(source.getSortOrder()); + target.setVisible(source.isVisible()); + target.setFeatured(source.isFeatured()); + } + + private com.salesmanager.shop.model.catalog.category.CategoryDescription convertDescription( + CategoryDescription description) { + final com.salesmanager.shop.model.catalog.category.CategoryDescription desc = + new com.salesmanager.shop.model.catalog.category.CategoryDescription(); + + desc.setFriendlyUrl(description.getSeUrl()); + desc.setName(description.getName()); + desc.setId(description.getId()); + desc.setDescription(description.getDescription()); + desc.setKeyWords(description.getMetatagKeywords()); + desc.setHighlights(description.getCategoryHighlight()); + desc.setLanguage(description.getLanguage().getCode()); + desc.setTitle(description.getMetatagTitle()); + desc.setMetaDescription(description.getMetatagDescription()); + return desc; + } + + + private Optional createParentCategory( + Category source) { + return Optional.ofNullable(source.getParent()).map(parentValue -> { + final com.salesmanager.shop.model.catalog.category.Category parent = + new com.salesmanager.shop.model.catalog.category.Category(); + parent.setCode(source.getParent().getCode()); + parent.setId(source.getParent().getId()); + return parent; + }); + } + + @Override + public ReadableCategory merge(Category source, ReadableCategory destination, + MerchantStore store, Language language) { + return destination; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableManufacturerMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableManufacturerMapper.java new file mode 100755 index 0000000000..405f08ddf1 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableManufacturerMapper.java @@ -0,0 +1,83 @@ +package com.salesmanager.shop.mapper.catalog; + +import java.util.Optional; +import java.util.Set; +import org.springframework.stereotype.Component; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.catalog.product.manufacturer.ManufacturerDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.manufacturer.ReadableManufacturer; + +@Component +public class ReadableManufacturerMapper implements Mapper { + + @Override + public ReadableManufacturer convert(Manufacturer source, MerchantStore store, Language language) { + + if(language == null) { + language = store.getDefaultLanguage(); + } + ReadableManufacturer target = new ReadableManufacturer(); + + Optional description = + getDescription(source, language, target); + description.ifPresent(target::setDescription); + + target.setCode(source.getCode()); + target.setId(source.getId()); + target.setOrder(source.getOrder()); + Optional desc = this.getDescription(source, language, target); + if(description.isPresent()) { + target.setDescription(desc.get()); + } + + + return target; + } + + private Optional getDescription( + Manufacturer source, Language language, ReadableManufacturer target) { + + Optional description = + getDescription(source.getDescriptions(), language); + if (source.getDescriptions() != null && !source.getDescriptions().isEmpty() + && description.isPresent()) { + return Optional.of(convertDescription(description.get(), source)); + } else { + return Optional.empty(); + } + } + + private Optional getDescription( + Set descriptionsLang, Language language) { + Optional descriptionByLang = descriptionsLang.stream() + .filter(desc -> desc.getLanguage().getCode().equals(language.getCode())).findAny(); + if (descriptionByLang.isPresent()) { + return descriptionByLang; + } else { + return Optional.empty(); + } + } + + private com.salesmanager.shop.model.catalog.manufacturer.ManufacturerDescription convertDescription( + ManufacturerDescription description, Manufacturer source) { + final com.salesmanager.shop.model.catalog.manufacturer.ManufacturerDescription desc = + new com.salesmanager.shop.model.catalog.manufacturer.ManufacturerDescription(); + + desc.setFriendlyUrl(description.getUrl()); + desc.setId(description.getId()); + desc.setLanguage(description.getLanguage().getCode()); + desc.setName(description.getName()); + desc.setDescription(description.getDescription()); + return desc; + } + + @Override + public ReadableManufacturer merge(Manufacturer source, ReadableManufacturer destination, + MerchantStore store, Language language) { + return destination; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableMinimalProductMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableMinimalProductMapper.java new file mode 100644 index 0000000000..3993a3c10b --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableMinimalProductMapper.java @@ -0,0 +1,158 @@ +package com.salesmanager.shop.mapper.catalog; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.description.ProductDescription; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.ReadableImage; +import com.salesmanager.shop.model.catalog.product.ReadableMinimalProduct; +import com.salesmanager.shop.model.catalog.product.product.ProductSpecification; +import com.salesmanager.shop.model.entity.ReadableDescription; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.utils.DateUtil; +import com.salesmanager.shop.utils.ImageFilePath; + +@Component +public class ReadableMinimalProductMapper implements Mapper { + + @Autowired + private PricingService pricingService; + + + @Autowired + @Qualifier("img") + private ImageFilePath imageUtils; + + @Override + public ReadableMinimalProduct convert(Product source, MerchantStore store, Language language) { + // TODO Auto-generated method stub + ReadableMinimalProduct minimal = new ReadableMinimalProduct(); + return this.merge(source, minimal, store, language); + } + + @Override + public ReadableMinimalProduct merge(Product source, ReadableMinimalProduct destination, MerchantStore store, + Language language) { + Validate.notNull(source, "Product cannot be null"); + Validate.notNull(destination, "ReadableMinimalProduct cannot be null"); + + + for (ProductDescription desc : source.getDescriptions()) { + if (language != null && desc.getLanguage() != null + && desc.getLanguage().getId().intValue() == language.getId().intValue()) { + destination.setDescription(this.description(desc)); + break; + } + } + + destination.setId(source.getId()); + destination.setAvailable(source.isAvailable()); + destination.setProductShipeable(source.isProductShipeable()); + + ProductSpecification specifications = new ProductSpecification(); + specifications.setHeight(source.getProductHeight()); + specifications.setLength(source.getProductLength()); + specifications.setWeight(source.getProductWeight()); + specifications.setWidth(source.getProductWidth()); + destination.setProductSpecifications(specifications); + + destination.setPreOrder(source.isPreOrder()); + destination.setRefSku(source.getRefSku()); + destination.setSortOrder(source.getSortOrder()); + destination.setSku(source.getSku()); + + if(source.getDateAvailable() != null) { + destination.setDateAvailable(DateUtil.formatDate(source.getDateAvailable())); + } + + if(source.getProductReviewAvg()!=null) { + double avg = source.getProductReviewAvg().doubleValue(); + double rating = Math.round(avg * 2) / 2.0f; + destination.setRating(rating); + } + + destination.setProductVirtual(source.getProductVirtual()); + if(source.getProductReviewCount()!=null) { + destination.setRatingCount(source.getProductReviewCount().intValue()); + } + + //price + + try { + FinalPrice price = pricingService.calculateProductPrice(source); + if(price != null) { + + destination.setFinalPrice(pricingService.getDisplayAmount(price.getFinalPrice(), store)); + destination.setPrice(price.getFinalPrice()); + destination.setOriginalPrice(pricingService.getDisplayAmount(price.getOriginalPrice(), store)); + + } + } catch (ServiceException e) { + throw new ConversionRuntimeException("An error occured during price calculation", e); + } + + + + //image + Set images = source.getImages(); + if(images!=null && images.size()>0) { + List imageList = new ArrayList(); + + String contextPath = imageUtils.getContextPath(); + + for(ProductImage img : images) { + ReadableImage prdImage = new ReadableImage(); + prdImage.setImageName(img.getProductImage()); + prdImage.setDefaultImage(img.isDefaultImage()); + + StringBuilder imgPath = new StringBuilder(); + imgPath.append(contextPath).append(imageUtils.buildProductImageUtils(store, source.getSku(), img.getProductImage())); + + prdImage.setImageUrl(imgPath.toString()); + prdImage.setId(img.getId()); + prdImage.setImageType(img.getImageType()); + if(img.getProductImageUrl()!=null){ + prdImage.setExternalUrl(img.getProductImageUrl()); + } + if(img.getImageType()==1 && img.getProductImageUrl()!=null) {//video + prdImage.setVideoUrl(img.getProductImageUrl()); + } + + if(prdImage.isDefaultImage()) { + destination.setImage(prdImage); + } + + imageList.add(prdImage); + } + destination + .setImages(imageList); + } + + + return null; + } + + private ReadableDescription description(ProductDescription description) { + ReadableDescription desc = new ReadableDescription(); + desc.setDescription(description.getDescription()); + desc.setName(description.getName()); + desc.setId(description.getId()); + desc.setLanguage(description.getLanguage().getCode()); + return desc; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductAttributeMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductAttributeMapper.java new file mode 100644 index 0000000000..d82b199f44 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductAttributeMapper.java @@ -0,0 +1,79 @@ +package com.salesmanager.shop.mapper.catalog; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductAttributeEntity; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionEntity; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionValue; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; + +@Component +public class ReadableProductAttributeMapper implements Mapper { + + @Autowired + private ReadableProductOptionMapper readableProductOptionMapper; + + @Autowired + private ReadableProductOptionValueMapper readableProductOptionValueMapper; + + @Autowired + private PricingService pricingService; + + + @Override + public ReadableProductAttributeEntity convert(ProductAttribute source, MerchantStore store, Language language) { + ReadableProductAttributeEntity productAttribute = new ReadableProductAttributeEntity(); + return merge(source, productAttribute, store, language); + } + + @Override + public ReadableProductAttributeEntity merge(ProductAttribute source, ReadableProductAttributeEntity destination, + MerchantStore store, Language language) { + + ReadableProductAttributeEntity attr = new ReadableProductAttributeEntity(); + if(destination !=null) { + attr = destination; + } + try { + attr.setId(source.getId());//attribute of the option + + if(source.getProductAttributePrice()!=null && source.getProductAttributePrice().doubleValue()>0) { + String formatedPrice; + formatedPrice = pricingService.getDisplayAmount(source.getProductAttributePrice(), store); + attr.setProductAttributePrice(formatedPrice); + attr.setProductAttributeUnformattedPrice(pricingService.getStringAmount(source.getProductAttributePrice(), store)); + } + + attr.setProductAttributeWeight(source.getAttributeAdditionalWeight()); + attr.setAttributeDisplayOnly(source.getAttributeDisplayOnly()); + attr.setAttributeDefault(source.getAttributeDefault()); + if(!StringUtils.isBlank(source.getAttributeSortOrder())) { + attr.setSortOrder(Integer.parseInt(source.getAttributeSortOrder())); + } + + if(source.getProductOption()!=null) { + ReadableProductOptionEntity option = readableProductOptionMapper.convert(source.getProductOption(), store, language); + attr.setOption(option); + } + + if(source.getProductOptionValue()!=null) { + ReadableProductOptionValue optionValue = readableProductOptionValueMapper.convert(source.getProductOptionValue(), store, language); + attr.setOptionValue(optionValue); + } + + } catch (Exception e) { + throw new ConversionRuntimeException("Exception while product attribute conversion",e); + } + + + return attr; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductImageMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductImageMapper.java new file mode 100644 index 0000000000..d700d5df09 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductImageMapper.java @@ -0,0 +1,57 @@ +package com.salesmanager.shop.mapper.catalog; + +import javax.inject.Inject; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.ReadableImage; +import com.salesmanager.shop.utils.ImageFilePath; + +@Component +public class ReadableProductImageMapper implements Mapper { + + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + @Override + public ReadableImage convert(ProductImage source, MerchantStore store, Language language) { + ReadableImage destination = new ReadableImage(); + return merge(source, destination, store, language); + } + + @Override + public ReadableImage merge(ProductImage source, ReadableImage destination, MerchantStore store, Language language) { + + String contextPath = imageUtils.getContextPath(); + + destination.setImageName(source.getProductImage()); + destination.setDefaultImage(source.isDefaultImage()); + destination.setOrder(source.getSortOrder() != null ? source.getSortOrder().intValue() : 0); + + if (source.getImageType() == 1 && source.getProductImageUrl()!=null) { + destination.setImageUrl(source.getProductImageUrl()); + } else { + StringBuilder imgPath = new StringBuilder(); + imgPath.append(contextPath).append(imageUtils.buildProductImageUtils(store, source.getProduct().getSku(), source.getProductImage())); + destination.setImageUrl(imgPath.toString()); + } + destination.setId(source.getId()); + destination.setImageType(source.getImageType()); + if(source.getProductImageUrl()!=null){ + destination.setExternalUrl(source.getProductImageUrl()); + } + if(source.getImageType()==1 && source.getProductImageUrl()!=null) {//video + destination.setVideoUrl(source.getProductImageUrl()); + } + + return destination; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductOptionMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductOptionMapper.java new file mode 100644 index 0000000000..20be60d341 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductOptionMapper.java @@ -0,0 +1,69 @@ +package com.salesmanager.shop.mapper.catalog; + +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.collections4.CollectionUtils; +import org.springframework.stereotype.Component; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionEntity; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionFull; + +@Component +public class ReadableProductOptionMapper implements Mapper { + + @Override + public ReadableProductOptionEntity convert(ProductOption source, MerchantStore store, + Language language) { + ReadableProductOptionEntity destination = new ReadableProductOptionEntity(); + return merge(source, destination, store, language); + } + + + @Override + public ReadableProductOptionEntity merge(ProductOption source, + ReadableProductOptionEntity destination, MerchantStore store, Language language) { + ReadableProductOptionEntity readableProductOption = new ReadableProductOptionEntity(); + if(language == null) { + readableProductOption = new ReadableProductOptionFull(); + List descriptions = new ArrayList(); + for(ProductOptionDescription desc : source.getDescriptions()) { + com.salesmanager.shop.model.catalog.product.attribute.ProductOptionDescription d = this.description(desc); + descriptions.add(d); + } + ((ReadableProductOptionFull)readableProductOption).setDescriptions(descriptions); + } else { + readableProductOption = new ReadableProductOptionEntity(); + if(!CollectionUtils.isEmpty(source.getDescriptions())) { + for(ProductOptionDescription desc : source.getDescriptions()) { + if(desc != null && desc.getLanguage()!= null && desc.getLanguage().getId() == language.getId()) { + com.salesmanager.shop.model.catalog.product.attribute.ProductOptionDescription d = this.description(desc); + readableProductOption.setDescription(d); + } + } + } + } + + readableProductOption.setCode(source.getCode()); + readableProductOption.setId(source.getId()); + readableProductOption.setType(source.getProductOptionType()); + + + return readableProductOption; + } + + + + com.salesmanager.shop.model.catalog.product.attribute.ProductOptionDescription description(ProductOptionDescription description) { + com.salesmanager.shop.model.catalog.product.attribute.ProductOptionDescription desc = new com.salesmanager.shop.model.catalog.product.attribute.ProductOptionDescription(); + desc.setDescription(description.getDescription()); + desc.setName(description.getName()); + desc.setId(description.getId()); + desc.setLanguage(description.getLanguage().getCode()); + return desc; + } + +} \ No newline at end of file diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductOptionSetMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductOptionSetMapper.java new file mode 100644 index 0000000000..278587b0df --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductOptionSetMapper.java @@ -0,0 +1,116 @@ +package com.salesmanager.shop.mapper.catalog; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.CollectionUtils; +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionSet; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValueDescription; +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductOption; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductOptionValue; +import com.salesmanager.shop.model.catalog.product.attribute.optionset.ReadableProductOptionSet; +import com.salesmanager.shop.model.catalog.product.type.ReadableProductType; + +@Component +public class ReadableProductOptionSetMapper implements Mapper { + + + @Autowired + private ReadableProductTypeMapper readableProductTypeMapper; + + @Override + public ReadableProductOptionSet convert(ProductOptionSet source, MerchantStore store, Language language) { + ReadableProductOptionSet optionSource = new ReadableProductOptionSet(); + return merge(source, optionSource, store, language); + } + + @Override + public ReadableProductOptionSet merge(ProductOptionSet source, ReadableProductOptionSet destination, + MerchantStore store, Language language) { + Validate.notNull(source,"ProductOptionSet must not be null"); + Validate.notNull(destination,"ReadableProductOptionSet must not be null"); + + + destination.setId(source.getId()); + destination.setCode(source.getCode()); + destination.setReadOnly(source.isOptionDisplayOnly()); + + destination.setOption(this.option(source.getOption(), store, language)); + + List ids = new ArrayList(); + + if(!CollectionUtils.isEmpty(source.getValues())) { + List values = source.getValues().stream().map(val -> optionValue(ids, val, store, language)).collect(Collectors.toList()); + destination.setValues(values); + destination.getValues().removeAll(Collections.singleton(null)); + } + + if(!CollectionUtils.isEmpty(source.getProductTypes())) { + List types = source.getProductTypes().stream().map( t -> this.productType(t, store, language)).collect(Collectors.toList()); + destination.setProductTypes(types); + } + + + return destination; + } + + private ReadableProductOption option (ProductOption option, MerchantStore store, Language lang) { + + ReadableProductOption opt = new ReadableProductOption(); + opt.setCode(option.getCode()); + opt.setId(option.getId()); + opt.setLang(lang.getCode()); + opt.setReadOnly(option.isReadOnly()); + opt.setType(option.getProductOptionType()); + ProductOptionDescription desc = this.optionDescription(option.getDescriptions(), lang); + if(desc != null) { + opt.setName(desc.getName()); + } + + return opt; + } + + private ReadableProductOptionValue optionValue (List ids, ProductOptionValue optionValue, MerchantStore store, Language language) { + + if(!ids.contains(optionValue.getId())) { + ReadableProductOptionValue value = new ReadableProductOptionValue(); + value.setCode(optionValue.getCode()); + value.setId(optionValue.getId()); + ProductOptionValueDescription desc = optionValueDescription(optionValue.getDescriptions(), language); + if(desc!=null) { + value.setName(desc.getName()); + } + ids.add(optionValue.getId()); + return value; + } else { + return null; + } + } + + private ProductOptionDescription optionDescription(Set descriptions, Language lang) { + return descriptions.stream().filter(desc-> desc.getLanguage().getCode().equals(lang.getCode())).findAny().orElse(null); + } + + private ProductOptionValueDescription optionValueDescription(Set descriptions, Language lang) { + return descriptions.stream().filter(desc-> desc.getLanguage().getCode().equals(lang.getCode())).findAny().orElse(null); + } + + private ReadableProductType productType(ProductType type, MerchantStore store, Language language) { + return readableProductTypeMapper.convert(type, store, language); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductOptionValueMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductOptionValueMapper.java new file mode 100644 index 0000000000..6cacc78c1d --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductOptionValueMapper.java @@ -0,0 +1,84 @@ +package com.salesmanager.shop.mapper.catalog; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValueDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionValue; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionValueFull; +import com.salesmanager.shop.utils.ImageFilePath; + +@Component +public class ReadableProductOptionValueMapper implements Mapper { + + @Autowired + @Qualifier("img") + private ImageFilePath imageUtils; + + @Override + public ReadableProductOptionValue merge(ProductOptionValue source, ReadableProductOptionValue destination, + MerchantStore store, Language language) { + ReadableProductOptionValue readableProductOptionValue = new ReadableProductOptionValue(); + if(language == null) { + readableProductOptionValue = new ReadableProductOptionValueFull(); + List descriptions = new ArrayList(); + for(ProductOptionValueDescription desc : source.getDescriptions()) { + com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription d = this.description(desc); + descriptions.add(d); + } + ((ReadableProductOptionValueFull)readableProductOptionValue).setDescriptions(descriptions); + } else { + readableProductOptionValue = new ReadableProductOptionValue(); + if(!CollectionUtils.isEmpty(source.getDescriptions())) { + for(ProductOptionValueDescription desc : source.getDescriptions()) { + if(desc != null && desc.getLanguage()!= null && desc.getLanguage().getId() == language.getId()) { + com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription d = this.description(desc); + readableProductOptionValue.setDescription(d); + } + } + } + } + + readableProductOptionValue.setCode(source.getCode()); + if(source.getId()!=null) { + readableProductOptionValue.setId(source.getId().longValue()); + } + if(source.getProductOptionValueSortOrder()!=null) { + readableProductOptionValue.setOrder(source.getProductOptionValueSortOrder().intValue()); + } + if(!StringUtils.isBlank(source.getProductOptionValueImage())) { + readableProductOptionValue.setImage(imageUtils.buildProductPropertyImageUtils(store, source.getProductOptionValueImage())); + } + + return readableProductOptionValue; + } + + + + com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription description(ProductOptionValueDescription description) { + com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription desc = new com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription(); + desc.setDescription(description.getDescription()); + desc.setName(description.getName()); + desc.setId(description.getId()); + desc.setLanguage(description.getLanguage().getCode()); + return desc; + } + + +@Override +public ReadableProductOptionValue convert(ProductOptionValue source, MerchantStore store, Language language) { + ReadableProductOptionValue destination = new ReadableProductOptionValue(); + return merge(source, destination, store, language); +} + +} \ No newline at end of file diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductTypeMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductTypeMapper.java new file mode 100644 index 0000000000..677d9122d9 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductTypeMapper.java @@ -0,0 +1,74 @@ +package com.salesmanager.shop.mapper.catalog; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.type.ProductTypeDescription; +import com.salesmanager.shop.model.catalog.product.type.ReadableProductType; +import com.salesmanager.shop.model.catalog.product.type.ReadableProductTypeFull; + +@Component +public class ReadableProductTypeMapper implements Mapper { + + @Override + public ReadableProductType convert(ProductType source, MerchantStore store, Language language) { + ReadableProductType type = new ReadableProductType(); + return this.merge(source, type, store, language); + } + + @Override + public ReadableProductType merge(ProductType source, ReadableProductType destination, MerchantStore store, + Language language) { + Validate.notNull(source, "ProductType cannot be null"); + Validate.notNull(destination, "ReadableProductType cannot be null"); + return type(source, language); + } + + private ReadableProductType type (ProductType type, Language language) { + ReadableProductType readableType = null; + + + if(language != null) { + readableType = new ReadableProductType(); + if(!CollectionUtils.isEmpty(type.getDescriptions())) { + Optional desc = type.getDescriptions().stream().filter(t -> t.getLanguage().getCode().equals(language.getCode())) + .map(d -> typeDescription(d)).findFirst(); + if(desc.isPresent()) { + readableType.setDescription(desc.get()); + } + } + } else { + + readableType = new ReadableProductTypeFull(); + List descriptions = type.getDescriptions().stream().map(t -> this.typeDescription(t)).collect(Collectors.toList()); + ((ReadableProductTypeFull)readableType).setDescriptions(descriptions); + + } + + readableType.setCode(type.getCode()); + readableType.setId(type.getId()); + readableType.setVisible(type.getVisible() != null && type.getVisible().booleanValue() ? true:false); + readableType.setAllowAddToCart(type.getAllowAddToCart() != null && type.getAllowAddToCart().booleanValue() ? true:false); + + return readableType; + } + + private ProductTypeDescription typeDescription(com.salesmanager.core.model.catalog.product.type.ProductTypeDescription description) { + ProductTypeDescription desc = new ProductTypeDescription(); + desc.setId(description.getId()); + desc.setName(description.getName()); + desc.setDescription(description.getDescription()); + desc.setLanguage(description.getLanguage().getCode()); + return desc; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductVariationMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductVariationMapper.java new file mode 100644 index 0000000000..bc05714b56 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/ReadableProductVariationMapper.java @@ -0,0 +1,85 @@ +package com.salesmanager.shop.mapper.catalog; + +import java.util.Set; + +import org.jsoup.helper.Validate; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValueDescription; +import com.salesmanager.core.model.catalog.product.variation.ProductVariation; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductOption; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductOptionValue; +import com.salesmanager.shop.model.catalog.product.variation.ReadableProductVariation; + +@Component +public class ReadableProductVariationMapper implements Mapper { + + + @Override + public ReadableProductVariation convert(ProductVariation source, MerchantStore store, Language language) { + ReadableProductVariation variation = new ReadableProductVariation(); + return merge(source, variation, store, language); + } + + @Override + public ReadableProductVariation merge(ProductVariation source, ReadableProductVariation destination, + MerchantStore store, Language language) { + + Validate.notNull(source,"ProductVariation must not be null"); + Validate.notNull(destination,"ReadableProductVariation must not be null"); + + + destination.setId(source.getId()); + destination.setCode(source.getCode()); + + + destination.setOption(this.option(source.getProductOption(), language)); + destination.setOptionValue(this.optionValue(source.getProductOptionValue(), store, language)); + + return destination; + } + + private ReadableProductOption option (ProductOption option, Language lang) { + + ReadableProductOption opt = new ReadableProductOption(); + opt.setCode(option.getCode()); + opt.setId(option.getId()); + opt.setLang(lang.getCode()); + opt.setReadOnly(option.isReadOnly()); + opt.setType(option.getProductOptionType()); + ProductOptionDescription desc = this.optionDescription(option.getDescriptions(), lang); + if(desc != null) { + opt.setName(desc.getName()); + } + + return opt; + } + + private ReadableProductOptionValue optionValue (ProductOptionValue val, MerchantStore store, Language language) { + + ReadableProductOptionValue value = new ReadableProductOptionValue(); + value.setCode(val.getCode()); + value.setId(val.getId()); + ProductOptionValueDescription desc = optionValueDescription(val.getDescriptions(), language); + if(desc!=null) { + value.setName(desc.getName()); + } + return value; + + } + + private ProductOptionDescription optionDescription(Set descriptions, Language lang) { + return descriptions.stream().filter(desc-> desc.getLanguage().getCode().equals(lang.getCode())).findAny().orElse(null); + } + + private ProductOptionValueDescription optionValueDescription(Set descriptions, Language lang) { + return descriptions.stream().filter(desc-> desc.getLanguage().getCode().equals(lang.getCode())).findAny().orElse(null); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/PersistableProductAvailabilityMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/PersistableProductAvailabilityMapper.java new file mode 100644 index 0000000000..249e40f197 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/PersistableProductAvailabilityMapper.java @@ -0,0 +1,86 @@ +package com.salesmanager.shop.mapper.catalog.product; + +import java.util.Date; +import java.util.Optional; + +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPriceDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.product.PersistableProductInventory; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.utils.DateUtil; + +@Component +public class PersistableProductAvailabilityMapper implements Mapper { + + @Override + public ProductAvailability convert(PersistableProductInventory source, MerchantStore store, Language language) { + return this.merge(source, new ProductAvailability(), store, language); + } + + @Override + public ProductAvailability merge(PersistableProductInventory source, ProductAvailability destination, + MerchantStore store, Language language) { + + try { + + destination.setRegion(Constants.ALL_REGIONS); + + destination.setProductQuantity(source.getQuantity()); + destination.setProductQuantityOrderMin(1); + destination.setProductQuantityOrderMax(1); + + if (source.getPrice() != null) { + + ProductPrice price = new ProductPrice(); + price.setProductAvailability(destination); + price.setDefaultPrice(source.getPrice().isDefaultPrice()); + price.setProductPriceAmount(source.getPrice().getPrice()); + price.setCode(source.getPrice().getCode()); + price.setProductPriceSpecialAmount(source.getPrice().getDiscountedPrice()); + if (source.getPrice().getDiscountStartDate() != null) { + Date startDate; + + startDate = DateUtil.getDate(source.getPrice().getDiscountStartDate()); + + price.setProductPriceSpecialStartDate(startDate); + } + if (source.getPrice().getDiscountEndDate() != null) { + Date endDate = DateUtil.getDate(source.getPrice().getDiscountEndDate()); + price.setProductPriceSpecialEndDate(endDate); + } + destination.getPrices().add(price); + for (Language lang : store.getLanguages()) { + ProductPriceDescription ppd = new ProductPriceDescription(); + ppd.setProductPrice(price); + ppd.setLanguage(lang); + ppd.setName(ProductPriceDescription.DEFAULT_PRICE_DESCRIPTION); + + // price appender + Optional description = source + .getPrice().getDescriptions().stream() + .filter(d -> d.getLanguage() != null && d.getLanguage().equals(lang.getCode())).findFirst(); + if (description.isPresent()) { + ppd.setPriceAppender(description.get().getPriceAppender()); + } + price.getDescriptions().add(ppd); + } + + } + + + + } catch (Exception e) { + throw new ServiceRuntimeException("An error occured while mapping product availability", e); + } + + return destination; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/PersistableProductDefinitionMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/PersistableProductDefinitionMapper.java new file mode 100644 index 0000000000..526432c5a8 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/PersistableProductDefinitionMapper.java @@ -0,0 +1,297 @@ +package com.salesmanager.shop.mapper.catalog.product; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.catalog.category.CategoryService; +import com.salesmanager.core.business.services.catalog.product.manufacturer.ManufacturerService; +import com.salesmanager.core.business.services.catalog.product.type.ProductTypeService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.description.ProductDescription; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPriceDescription; +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.mapper.catalog.PersistableProductAttributeMapper; +import com.salesmanager.shop.model.catalog.product.ProductPriceEntity; +import com.salesmanager.shop.model.catalog.product.product.definition.PersistableProductDefinition; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.utils.DateUtil; + +@Component +public class PersistableProductDefinitionMapper implements Mapper { + + @Autowired + private CategoryService categoryService; + @Autowired + private LanguageService languageService; + @Autowired + private PersistableProductAttributeMapper persistableProductAttributeMapper; + + @Autowired + private ProductTypeService productTypeService; + + @Autowired + private ManufacturerService manufacturerService; + + @Override + public Product convert(PersistableProductDefinition source, MerchantStore store, Language language) { + Product product = new Product(); + return this.merge(source, product, store, language); + } + + @Override + public Product merge(PersistableProductDefinition source, Product destination, MerchantStore store, + Language language) { + + + + Validate.notNull(destination,"Product must not be null"); + + try { + + //core properties + + if(StringUtils.isBlank(source.getIdentifier())) { + destination.setSku(source.getSku()); + } else { + destination.setSku(source.getIdentifier()); + } + destination.setAvailable(source.isVisible()); + destination.setDateAvailable(new Date()); + + destination.setRefSku(source.getIdentifier()); + + + if(source.getId() != null && source.getId().longValue()==0) { + destination.setId(null); + } else { + destination.setId(source.getId()); + } + + //MANUFACTURER + if(!StringUtils.isBlank(source.getManufacturer())) { + Manufacturer manufacturer = manufacturerService.getByCode(store, source.getManufacturer()); + if(manufacturer == null) { + throw new ConversionException("Manufacturer [" + source.getManufacturer() + "] does not exist"); + } + destination.setManufacturer(manufacturer); + } + + + //PRODUCT TYPE + if(!StringUtils.isBlank(source.getType())) { + ProductType type = productTypeService.getByCode(source.getType(), store, language); + if(type == null) { + throw new ConversionException("Product type [" + source.getType() + "] does not exist"); + } + + destination.setType(type); + } + + + if(!StringUtils.isBlank(source.getDateAvailable())) { + destination.setDateAvailable(DateUtil.getDate(source.getDateAvailable())); + } + + + + destination.setMerchantStore(store); + + List languages = new ArrayList(); + Set descriptions = new HashSet(); + if(!CollectionUtils.isEmpty(source.getDescriptions())) { + for(com.salesmanager.shop.model.catalog.product.ProductDescription description : source.getDescriptions()) { + + ProductDescription productDescription = new ProductDescription(); + Language lang = languageService.getByCode(description.getLanguage()); + if(lang==null) { + throw new ConversionException("Language code " + description.getLanguage() + " is invalid, use ISO code (en, fr ...)"); + } + if(!CollectionUtils.isEmpty(destination.getDescriptions())) { + for(ProductDescription desc : destination.getDescriptions()) { + if(desc.getLanguage().getCode().equals(description.getLanguage())) { + productDescription = desc; + break; + } + } + } + + productDescription.setProduct(destination); + productDescription.setDescription(description.getDescription()); + + productDescription.setProductHighlight(description.getHighlights()); + + productDescription.setName(description.getName()); + productDescription.setSeUrl(description.getFriendlyUrl()); + productDescription.setMetatagKeywords(description.getKeyWords()); + productDescription.setMetatagDescription(description.getMetaDescription()); + productDescription.setTitle(description.getTitle()); + + languages.add(lang); + productDescription.setLanguage(lang); + descriptions.add(productDescription); + } + } + + if(descriptions.size()>0) { + destination.setDescriptions(descriptions); + } + + /** + * Product definition + */ + ProductAvailability productAvailability = null; + ProductPrice defaultPrice = null; + if(!CollectionUtils.isEmpty(destination.getAvailabilities())) { + for(ProductAvailability avail : destination.getAvailabilities()) { + Set prices = avail.getPrices(); + for(ProductPrice p : prices) { + if(p.isDefaultPrice()) { + if(productAvailability == null) { + productAvailability = avail; + defaultPrice = p; + productAvailability.setProductQuantity(source.getQuantity()); + productAvailability.setProductStatus(source.isCanBePurchased()); + p.setProductPriceAmount(source.getPrice()); + break; + } + } + } + } + } + + if(productAvailability == null) { //create with default values + productAvailability = new ProductAvailability(destination, store); + destination.getAvailabilities().add(productAvailability); + + productAvailability.setProductQuantity(source.getQuantity()); + productAvailability.setProductQuantityOrderMin(1); + productAvailability.setProductQuantityOrderMax(1); + productAvailability.setRegion(Constants.ALL_REGIONS); + productAvailability.setAvailable(Boolean.valueOf(destination.isAvailable())); + productAvailability.setProductStatus(source.isCanBePurchased()); + } + + + + + if(defaultPrice == null) { + + BigDecimal defaultPriceAmount = new BigDecimal(0); + if(source.getPrice() != null) { + defaultPriceAmount = source.getPrice(); + } + + defaultPrice = new ProductPrice(); + defaultPrice.setDefaultPrice(true); + defaultPrice.setProductPriceAmount(defaultPriceAmount); + defaultPrice.setCode(ProductPriceEntity.DEFAULT_PRICE_CODE); + defaultPrice.setProductAvailability(productAvailability); + productAvailability.getPrices().add(defaultPrice); + for(Language lang : languages) { + + ProductPriceDescription ppd = new ProductPriceDescription(); + ppd.setProductPrice(defaultPrice); + ppd.setLanguage(lang); + ppd.setName(ProductPriceDescription.DEFAULT_PRICE_DESCRIPTION); + defaultPrice.getDescriptions().add(ppd); + } + } + + if(source.getProductSpecifications()!=null) { + destination.setProductHeight(source.getProductSpecifications().getHeight()); + destination.setProductLength(source.getProductSpecifications().getLength()); + destination.setProductWeight(source.getProductSpecifications().getWeight()); + destination.setProductWidth(source.getProductSpecifications().getWidth()); + + + if(source.getProductSpecifications().getManufacturer()!=null) { + + Manufacturer manuf = null; + if(!StringUtils.isBlank(source.getProductSpecifications().getManufacturer())) { + manuf = manufacturerService.getByCode(store, source.getProductSpecifications().getManufacturer()); + } + + if(manuf==null) { + throw new ConversionException("Invalid manufacturer id"); + } + if(manuf!=null) { + if(manuf.getMerchantStore().getId().intValue()!=store.getId().intValue()) { + throw new ConversionException("Invalid manufacturer id"); + } + destination.setManufacturer(manuf); + } + } + + } + destination.setSortOrder(source.getSortOrder()); + destination.setProductVirtual(source.isVirtual()); + destination.setProductShipeable(source.isShipeable()); + + + //attributes + if(source.getProperties()!=null) { + for(com.salesmanager.shop.model.catalog.product.attribute.PersistableProductAttribute attr : source.getProperties()) { + ProductAttribute attribute = persistableProductAttributeMapper.convert(attr, store, language); + + attribute.setProduct(destination); + destination.getAttributes().add(attribute); + + } + } + + + //categories + if(!CollectionUtils.isEmpty(source.getCategories())) { + for(com.salesmanager.shop.model.catalog.category.Category categ : source.getCategories()) { + + Category c = null; + if(!StringUtils.isBlank(categ.getCode())) { + c = categoryService.getByCode(store, categ.getCode()); + } else { + Validate.notNull(categ.getId(), "Category id nust not be null"); + c = categoryService.getById(categ.getId(), store.getId()); + } + + if(c==null) { + if(!StringUtils.isBlank(categ.getCode())) { + throw new ConversionException("Category code " + categ.getCode() + " does not exist"); + } else { + throw new ConversionException("Category id " + categ.getId() + " does not exist"); + + } + } + if(c.getMerchantStore().getId().intValue()!=store.getId().intValue()) { + throw new ConversionException("Invalid category id"); + } + destination.getCategories().add(c); + } + } + return destination; + + } catch (Exception e) { + throw new ConversionRuntimeException("Error converting product mapper",e); + } + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/PersistableProductMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/PersistableProductMapper.java new file mode 100644 index 0000000000..6c78dec132 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/PersistableProductMapper.java @@ -0,0 +1,311 @@ +package com.salesmanager.shop.mapper.catalog.product; + +import java.io.ByteArrayInputStream; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.catalog.category.CategoryService; +import com.salesmanager.core.business.services.catalog.product.manufacturer.ManufacturerService; +import com.salesmanager.core.business.services.catalog.product.type.ProductTypeService; +import com.salesmanager.core.business.services.catalog.product.variant.ProductVariantService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.description.ProductDescription; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPriceDescription; +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.mapper.catalog.PersistableProductAttributeMapper; +import com.salesmanager.shop.model.catalog.product.PersistableImage; +import com.salesmanager.shop.model.catalog.product.ProductPriceEntity; +import com.salesmanager.shop.model.catalog.product.product.PersistableProduct; +import com.salesmanager.shop.model.catalog.product.product.PersistableProductInventory; +import com.salesmanager.shop.model.catalog.product.product.variant.PersistableProductVariant; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.utils.DateUtil; + + +/** + * Transforms a fully configured PersistableProduct + * to a Product with inventory and Variants if any + * @author carlsamson + * + */ + + +@Component +public class PersistableProductMapper implements Mapper { + + + @Autowired + private PersistableProductAvailabilityMapper persistableProductAvailabilityMapper; + + @Autowired + private PersistableProductVariantMapper persistableProductVariantMapper; + + + + @Autowired + private CategoryService categoryService; + @Autowired + private LanguageService languageService; + + + + @Autowired + private ManufacturerService manufacturerService; + + @Autowired + private ProductTypeService productTypeService; + + @Override + public Product convert(PersistableProduct source, MerchantStore store, Language language) { + Product product = new Product(); + return this.merge(source, product, store, language); + } + + @Override + public Product merge(PersistableProduct source, Product destination, MerchantStore store, Language language) { + + + Validate.notNull(destination,"Product must not be null"); + + try { + + //core properties + destination.setSku(source.getSku()); + + destination.setAvailable(source.isVisible()); + destination.setDateAvailable(new Date()); + + destination.setRefSku(source.getRefSku()); + + + if(source.getId() != null && source.getId().longValue()==0) { + destination.setId(null); + } else { + destination.setId(source.getId()); + } + + + /** + * SPEIFICATIONS + */ + if(source.getProductSpecifications()!=null) { + destination.setProductHeight(source.getProductSpecifications().getHeight()); + destination.setProductLength(source.getProductSpecifications().getLength()); + destination.setProductWeight(source.getProductSpecifications().getWeight()); + destination.setProductWidth(source.getProductSpecifications().getWidth()); + + /** + * BRANDING + */ + + if(source.getProductSpecifications().getManufacturer()!=null) { + + Manufacturer manufacturer = manufacturerService.getByCode(store, source.getProductSpecifications().getManufacturer()); + if(manufacturer == null) { + throw new ConversionException("Manufacturer [" + source.getProductSpecifications().getManufacturer() + "] does not exist"); + } + destination.setManufacturer(manufacturer); + } + } + + + //PRODUCT TYPE + if(!StringUtils.isBlank(source.getType())) { + ProductType type = productTypeService.getByCode(source.getType(), store, language); + if(type == null) { + throw new ConversionException("Product type [" + source.getType() + "] does not exist"); + } + destination.setType(type); + } + + + if(!StringUtils.isBlank(source.getDateAvailable())) { + destination.setDateAvailable(DateUtil.getDate(source.getDateAvailable())); + } + + destination.setMerchantStore(store); + + /** + * descriptions + */ + List languages = new ArrayList(); + Set descriptions = new HashSet(); + if(!CollectionUtils.isEmpty(source.getDescriptions())) { + for(com.salesmanager.shop.model.catalog.product.ProductDescription description : source.getDescriptions()) { + + ProductDescription productDescription = new ProductDescription(); + Language lang = languageService.getByCode(description.getLanguage()); + if(lang==null) { + throw new ConversionException("Language code " + description.getLanguage() + " is invalid, use ISO code (en, fr ...)"); + } + if(!CollectionUtils.isEmpty(destination.getDescriptions())) { + for(ProductDescription desc : destination.getDescriptions()) { + if(desc.getLanguage().getCode().equals(description.getLanguage())) { + productDescription = desc; + break; + } + } + } + + productDescription.setProduct(destination); + productDescription.setDescription(description.getDescription()); + + productDescription.setProductHighlight(description.getHighlights()); + + productDescription.setName(description.getName()); + productDescription.setSeUrl(description.getFriendlyUrl()); + productDescription.setMetatagKeywords(description.getKeyWords()); + productDescription.setMetatagDescription(description.getMetaDescription()); + productDescription.setTitle(description.getTitle()); + + languages.add(lang); + productDescription.setLanguage(lang); + descriptions.add(productDescription); + } + } + + if(descriptions.size()>0) { + destination.setDescriptions(descriptions); + } + + destination.setSortOrder(source.getSortOrder()); + destination.setProductVirtual(source.isProductVirtual()); + destination.setProductShipeable(source.isProductShipeable()); + if(source.getRating() != null) { + destination.setProductReviewAvg(new BigDecimal(source.getRating())); + } + destination.setProductReviewCount(source.getRatingCount()); + + + + /** + * Category + */ + + if(!CollectionUtils.isEmpty(source.getCategories())) { + for(com.salesmanager.shop.model.catalog.category.Category categ : source.getCategories()) { + + Category c = null; + if(!StringUtils.isBlank(categ.getCode())) { + c = categoryService.getByCode(store, categ.getCode()); + } else { + Validate.notNull(categ.getId(), "Category id nust not be null"); + c = categoryService.getById(categ.getId(), store.getId()); + } + + if(c==null) { + if(!StringUtils.isBlank(categ.getCode())) { + throw new ConversionException("Category code " + categ.getCode() + " does not exist"); + } else { + throw new ConversionException("Category id " + categ.getId() + " does not exist"); + } + } + if(c.getMerchantStore().getId().intValue()!=store.getId().intValue()) { + throw new ConversionException("Invalid category id"); + } + destination.getCategories().add(c); + } + } + + /** + * Variants + */ + if(!CollectionUtils.isEmpty(source.getVariants())) { + Set variants = source.getVariants().stream().map(v -> this.variant(destination, v, store, language)).collect(Collectors.toSet()); + + destination.setVariants(variants); + } + + /** + * Default inventory + */ + + if(source.getInventory() != null) { + ProductAvailability productAvailability = persistableProductAvailabilityMapper.convert(source.getInventory(), store, language); + productAvailability.setProduct(destination); + destination.getAvailabilities().add(productAvailability); + } else { + //need an inventory to create a Product + if(!CollectionUtils.isEmpty(destination.getVariants())) { + ProductAvailability defaultAvailability = null; + for(ProductVariant variant : destination.getVariants()) { + defaultAvailability = this.defaultAvailability(variant.getAvailabilities().stream().collect(Collectors.toList())); + if(defaultAvailability != null) { + break; + } + } + + defaultAvailability.setProduct(destination); + destination.getAvailabilities().add(defaultAvailability); + + } + } + + //images + if(!CollectionUtils.isEmpty(source.getImages())) { + for(PersistableImage img : source.getImages()) { + ProductImage productImage = new ProductImage(); + productImage.setImageType(img.getImageType()); + productImage.setDefaultImage(img.isDefaultImage()); + if (img.getImageType() == 1) {//external url + productImage.setProductImageUrl(img.getImageUrl()); + productImage.setImage(new ByteArrayInputStream(new byte[0])); + } else { + ByteArrayInputStream in = new ByteArrayInputStream(img.getBytes()); + productImage.setImage(in); + } + productImage.setProduct(destination); + productImage.setProductImage(img.getName()); + + destination.getImages().add(productImage); + } + } + + + return destination; + + } catch (Exception e) { + throw new ConversionRuntimeException("Error converting product mapper",e); + } + + + } + + private ProductVariant variant(Product product, PersistableProductVariant variant, MerchantStore store, Language language) { + ProductVariant var = persistableProductVariantMapper.convert(variant, store, language); + var.setProduct(product); + return var; + } + + private ProductAvailability defaultAvailability(List availabilityList) { + return availabilityList.stream().filter(a -> a.getRegion() != null && a.getRegion().equals(Constants.ALL_REGIONS)).findFirst().get(); + } + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/PersistableProductVariantGroupMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/PersistableProductVariantGroupMapper.java new file mode 100644 index 0000000000..86dc61ac8d --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/PersistableProductVariantGroupMapper.java @@ -0,0 +1,78 @@ +package com.salesmanager.shop.mapper.catalog.product; + +import java.util.HashSet; +import java.util.List; + +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.services.catalog.product.variant.ProductVariantImageService; +import com.salesmanager.core.business.services.catalog.product.variant.ProductVariantService; +import com.salesmanager.core.model.catalog.product.variant.ProductVariantImage; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.catalog.product.variant.ProductVariantGroup; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.product.variantGroup.PersistableProductVariantGroup; + +@Component +public class PersistableProductVariantGroupMapper implements Mapper{ + + + @Autowired + private ProductVariantService productVariantService; + + @Autowired + private ProductVariantImageService productVariantImageService; + + @Override + public ProductVariantGroup convert(PersistableProductVariantGroup source, MerchantStore store, + Language language) { + Validate.notNull(source, "PersistableproductVariantGroup cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + return this.merge(source, new ProductVariantGroup(), store, language); + } + + @Override + public ProductVariantGroup merge(PersistableProductVariantGroup source, ProductVariantGroup destination, + MerchantStore store, Language language) { + + Validate.notNull(source, "PersistableproductVariantGroup cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + Validate.notNull(source.getproductVariants(), "Product instances cannot be null"); + + if(destination == null) { + destination = new ProductVariantGroup(); + } + + destination.setId(source.getId()); + + + List productVariants = productVariantService.getByIds(source.getproductVariants(), store); + + for(ProductVariant p : productVariants) { + p.setProductVariantGroup(destination); + } + + //images are not managed from this object + if(source.getId() != null) { + List images = productVariantImageService.listByProductVariantGroup(source.getId(), store); + destination.setImages(images); + } + destination.setMerchantStore(store); + destination.setProductVariants(new HashSet(productVariants)); + return destination; + } + + private ProductVariant instance(ProductVariant instance, ProductVariantGroup group, MerchantStore store) { + + instance.setProductVariantGroup(group); + return instance; + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/PersistableProductVariantMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/PersistableProductVariantMapper.java new file mode 100644 index 0000000000..6215c1a2b1 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/PersistableProductVariantMapper.java @@ -0,0 +1,155 @@ +package com.salesmanager.shop.mapper.catalog.product; + +import java.util.Date; +import java.util.Optional; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.variation.ProductVariationService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.catalog.product.variation.ProductVariation; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.product.variant.PersistableProductVariant; +import com.salesmanager.shop.store.api.exception.OperationNotAllowedException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.utils.DateUtil; + +@Component +public class PersistableProductVariantMapper implements Mapper { + + @Autowired + private ProductVariationService productVariationService; + + @Autowired + private PersistableProductAvailabilityMapper persistableProductAvailabilityMapper; + + @Autowired + private ProductService productService; + + @Override + public ProductVariant convert(PersistableProductVariant source, MerchantStore store, Language language) { + ProductVariant productVariantModel = new ProductVariant(); + return this.merge(source, productVariantModel, store, language); + } + + @Override + public ProductVariant merge(PersistableProductVariant source, ProductVariant destination, MerchantStore store, + Language language) { + + // + Long productVariation = source.getVariation(); + Long productVariationValue = source.getVariationValue(); + + String productVariationCode = source.getVariationCode(); + String productVariationValueCode = source.getVariationValueCode(); + + Optional variation = null; + Optional variationValue = null; + + if(StringUtils.isEmpty(productVariationCode)) { + + variation = productVariationService.getById(store, productVariation); + if(productVariationValue != null) { + variationValue = productVariationService.getById(store, productVariationValue); + if(variationValue.isEmpty()) { + throw new ResourceNotFoundException("ProductVaritionValue [" + productVariationValue + "] + not found for store [" + store.getCode() + "]"); + } + + } + } else { + variation = productVariationService.getByCode(store, productVariationCode); + if(productVariationValueCode != null) { + variationValue = productVariationService.getByCode(store, productVariationValueCode); + if(variationValue.isEmpty()) { + throw new ResourceNotFoundException("ProductVaritionValue [" + productVariationValue + "] + not found for store [" + store.getCode() + "]"); + } + + } + } + + + if(variation.isEmpty()) { + throw new ResourceNotFoundException("ProductVarition [" + productVariation + "] + not found for store [" + store.getCode() + "]"); + } + + destination.setVariation(variation.get()); + + + if(productVariationValue != null) { + destination.setVariationValue(variationValue.get()); + } + + StringBuilder instanceCode = new StringBuilder(); + instanceCode.append(variation.get().getCode()); + if(productVariationValue != null && variationValue.get()!=null) { + instanceCode.append(":").append(variationValue.get().getCode()); + } + + destination.setCode(instanceCode.toString()); + + destination.setAvailable(source.isAvailable()); + destination.setDefaultSelection(source.isDefaultSelection()); + destination.setSku(source.getSku()); + + if(StringUtils.isBlank(source.getDateAvailable())) { + source.setDateAvailable(DateUtil.formatDate(new Date())); + } + + if(source.getDateAvailable()!=null) { + try { + destination.setDateAvailable(DateUtil.getDate(source.getDateAvailable())); + } catch (Exception e) { + throw new ServiceRuntimeException("Cant format date [" + source.getDateAvailable() + "]"); + } + } + + destination.setSortOrder(source.getSortOrder()); + + + /** + * Inventory + */ + if(source.getInventory() != null) { + ProductAvailability availability = persistableProductAvailabilityMapper.convert(source.getInventory(), store, language); + availability.setProductVariant(destination); + destination.getAvailabilities().add(availability); + } + + + Product product = null; + + if(source.getProductId() != null && source.getProductId().longValue() > 0) { + product = productService.findOne(source.getProductId(), store); + + if(product == null) { + throw new ResourceNotFoundException("Product [" + source.getId() + "] + not found for store [" + store.getCode() + "]"); + } + + if(product.getMerchantStore().getId() != store.getId()) { + throw new ResourceNotFoundException("Product [" + source.getId() + "] + not found for store [" + store.getCode() + "]"); + } + + if(product.getSku() != null && product.getSku().equals(source.getSku())) { + throw new OperationNotAllowedException("Product variant sku [" + source.getSku() + "] + must be different than product instance sku [" + product.getSku() + "]"); + } + + destination.setProduct(product); + + + } + + + + return destination; + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/ReadableProductDefinitionMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/ReadableProductDefinitionMapper.java new file mode 100644 index 0000000000..ce3677671d --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/ReadableProductDefinitionMapper.java @@ -0,0 +1,235 @@ +package com.salesmanager.shop.mapper.catalog.product; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.description.ProductDescription; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.mapper.catalog.ReadableCategoryMapper; +import com.salesmanager.shop.mapper.catalog.ReadableManufacturerMapper; +import com.salesmanager.shop.mapper.catalog.ReadableProductTypeMapper; +import com.salesmanager.shop.mapper.inventory.ReadableInventoryMapper; +import com.salesmanager.shop.model.catalog.category.ReadableCategory; +import com.salesmanager.shop.model.catalog.manufacturer.ReadableManufacturer; +import com.salesmanager.shop.model.catalog.product.ReadableImage; +import com.salesmanager.shop.model.catalog.product.inventory.ReadableInventory; +import com.salesmanager.shop.model.catalog.product.product.ProductSpecification; +import com.salesmanager.shop.model.catalog.product.product.definition.ReadableProductDefinition; +import com.salesmanager.shop.model.catalog.product.product.definition.ReadableProductDefinitionFull; +import com.salesmanager.shop.model.catalog.product.type.ReadableProductType; +import com.salesmanager.shop.model.references.DimensionUnitOfMeasure; +import com.salesmanager.shop.model.references.WeightUnitOfMeasure; +import com.salesmanager.shop.utils.DateUtil; +import com.salesmanager.shop.utils.ImageFilePath; + +@Component +public class ReadableProductDefinitionMapper implements Mapper { + + @Autowired + private ReadableCategoryMapper readableCategoryMapper; + + @Autowired + private ReadableProductTypeMapper readableProductTypeMapper; + + @Autowired + private ReadableManufacturerMapper readableManufacturerMapper; + + @Autowired + private ReadableInventoryMapper readableInventoryMapper; + + @Autowired + @Qualifier("img") + private ImageFilePath imageUtils; + + @Override + public ReadableProductDefinition convert(Product source, MerchantStore store, Language language) { + ReadableProductDefinition target = new ReadableProductDefinition(); + return this.merge(source, target, store, language); + } + + @Override + public ReadableProductDefinition merge(Product source, ReadableProductDefinition destination, MerchantStore store, + Language language) { + Validate.notNull(source, "Product cannot be null"); + Validate.notNull(destination, "Product destination cannot be null"); + + ReadableProductDefinition returnDestination = destination; + if (language == null) { + returnDestination = new ReadableProductDefinitionFull(); + } + + List fulldescriptions = new ArrayList(); + + returnDestination.setIdentifier(source.getSku()); + returnDestination.setId(source.getId()); + returnDestination.setVisible(source.isAvailable()); + returnDestination.setDateAvailable(DateUtil.formatDate(source.getDateAvailable())); + returnDestination.setSku(source.getSku()); + ProductDescription description = null; + if (source.getDescriptions() != null && source.getDescriptions().size() > 0) { + for (ProductDescription desc : source.getDescriptions()) { + if (language != null && desc.getLanguage() != null + && desc.getLanguage().getId().intValue() == language.getId().intValue()) { + description = desc; + break; + } else { + fulldescriptions.add(populateDescription(desc)); + } + } + } + +/* if (source.getProductReviewAvg() != null) { + double avg = source.getProductReviewAvg().doubleValue(); + double rating = Math.round(avg * 2) / 2.0f; + returnDestination.setRating(rating); + } + + if (source.getProductReviewCount() != null) { + returnDestination.setRatingCount(source.getProductReviewCount().intValue()); + }*/ + + if (description != null) { + com.salesmanager.shop.model.catalog.product.ProductDescription tragetDescription = populateDescription( + description); + returnDestination.setDescription(tragetDescription); + + } + + if (source.getManufacturer() != null) { + ReadableManufacturer manufacturer = readableManufacturerMapper.convert(source.getManufacturer(), store, + language); + returnDestination.setManufacturer(manufacturer); + } + + if (!CollectionUtils.isEmpty(source.getCategories())) { + List categoryList = new ArrayList(); + for (Category category : source.getCategories()) { + ReadableCategory readableCategory = readableCategoryMapper.convert(category, store, language); + categoryList.add(readableCategory); + + } + returnDestination.setCategories(categoryList); + } + + + ProductSpecification specifications = new ProductSpecification(); + specifications.setHeight(source.getProductHeight()); + specifications.setLength(source.getProductLength()); + specifications.setWeight(source.getProductWeight()); + specifications.setWidth(source.getProductWidth()); + if(!StringUtils.isBlank(store.getSeizeunitcode())) { + specifications.setDimensionUnitOfMeasure(DimensionUnitOfMeasure.valueOf(store.getSeizeunitcode().toLowerCase())); + } + if(!StringUtils.isBlank(store.getWeightunitcode())) { + specifications.setWeightUnitOfMeasure(WeightUnitOfMeasure.valueOf(store.getWeightunitcode().toLowerCase())); + } + returnDestination.setProductSpecifications(specifications); + + if (source.getType() != null) { + ReadableProductType readableType = readableProductTypeMapper.convert(source.getType(), store, language); + returnDestination.setType(readableType); + } + + returnDestination.setSortOrder(source.getSortOrder()); + + //images + Set images = source.getImages(); + if(CollectionUtils.isNotEmpty(images)) { + + List imageList = images.stream().map(i -> this.convertImage(source, i, store)).collect(Collectors.toList()); + returnDestination.setImages(imageList); + } + + //quantity + ProductAvailability availability = null; + for(ProductAvailability a : source.getAvailabilities()) { + availability = a; + if(a.getProductVariant() != null) { + continue; + } + } + + if(availability != null) { + returnDestination.setCanBePurchased(availability.getProductStatus()); + ReadableInventory inventory = readableInventoryMapper.convert(availability, store, language); + returnDestination.setInventory(inventory); + } + + + if (returnDestination instanceof ReadableProductDefinitionFull) { + ((ReadableProductDefinitionFull) returnDestination).setDescriptions(fulldescriptions); + } + + + + + return returnDestination; + } + + private ReadableImage convertImage(Product product, ProductImage image, MerchantStore store) { + ReadableImage prdImage = new ReadableImage(); + prdImage.setImageName(image.getProductImage()); + prdImage.setDefaultImage(image.isDefaultImage()); + + StringBuilder imgPath = new StringBuilder(); + imgPath.append(imageUtils.getContextPath()).append(imageUtils.buildProductImageUtils(store, product.getSku(), image.getProductImage())); + + prdImage.setImageUrl(imgPath.toString()); + prdImage.setId(image.getId()); + prdImage.setImageType(image.getImageType()); + if(image.getProductImageUrl()!=null){ + prdImage.setExternalUrl(image.getProductImageUrl()); + } + if(image.getImageType()==1 && image.getProductImageUrl()!=null) {//video + prdImage.setVideoUrl(image.getProductImageUrl()); + } + + if(prdImage.isDefaultImage()) { + prdImage.setDefaultImage(true); + } + + return prdImage; + } + + private com.salesmanager.shop.model.catalog.product.ProductDescription populateDescription(ProductDescription description) { + if (description == null) { + return null; + } + + com.salesmanager.shop.model.catalog.product.ProductDescription tragetDescription = new com.salesmanager.shop.model.catalog.product.ProductDescription(); + tragetDescription.setFriendlyUrl(description.getSeUrl()); + tragetDescription.setName(description.getName()); + tragetDescription.setId(description.getId()); + if (!StringUtils.isBlank(description.getMetatagTitle())) { + tragetDescription.setTitle(description.getMetatagTitle()); + } else { + tragetDescription.setTitle(description.getName()); + } + tragetDescription.setMetaDescription(description.getMetatagDescription()); + tragetDescription.setDescription(description.getDescription()); + tragetDescription.setHighlights(description.getProductHighlight()); + tragetDescription.setLanguage(description.getLanguage().getCode()); + tragetDescription.setKeyWords(description.getMetatagKeywords()); + + if (description.getLanguage() != null) { + tragetDescription.setLanguage(description.getLanguage().getCode()); + } + return tragetDescription; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/ReadableProductMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/ReadableProductMapper.java new file mode 100644 index 0000000000..89bd5eacf7 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/ReadableProductMapper.java @@ -0,0 +1,691 @@ +package com.salesmanager.shop.mapper.catalog.product; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.TreeMap; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValueDescription; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.description.ProductDescription; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPriceDescription; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.mapper.catalog.ReadableCategoryMapper; +import com.salesmanager.shop.mapper.catalog.ReadableManufacturerMapper; +import com.salesmanager.shop.mapper.catalog.ReadableProductTypeMapper; +import com.salesmanager.shop.model.catalog.category.ReadableCategory; +import com.salesmanager.shop.model.catalog.manufacturer.ReadableManufacturer; +import com.salesmanager.shop.model.catalog.product.ReadableImage; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.model.catalog.product.ReadableProductPrice; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductAttribute; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductAttributeValue; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductOption; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductProperty; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductPropertyValue; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionValue; +import com.salesmanager.shop.model.catalog.product.product.ProductSpecification; +import com.salesmanager.shop.model.catalog.product.product.variant.ReadableProductVariant; +import com.salesmanager.shop.model.catalog.product.type.ReadableProductType; +import com.salesmanager.shop.model.references.DimensionUnitOfMeasure; +import com.salesmanager.shop.model.references.WeightUnitOfMeasure; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.utils.DateUtil; +import com.salesmanager.shop.utils.ImageFilePath; + +/** + * Works for product v2 model + * + * @author carlsamson + * + */ +@Component +public class ReadableProductMapper implements Mapper { + + // uses code that is similar to ProductDefinition + @Autowired + @Qualifier("img") + private ImageFilePath imageUtils; + + @Autowired + private ReadableCategoryMapper readableCategoryMapper; + + @Autowired + private ReadableProductTypeMapper readableProductTypeMapper; + + @Autowired + private ReadableProductVariantMapper readableProductVariantMapper; + + @Autowired + private ReadableManufacturerMapper readableManufacturerMapper; + + @Autowired + private PricingService pricingService; + + @Override + public ReadableProduct convert(Product source, MerchantStore store, Language language) { + ReadableProduct product = new ReadableProduct(); + return this.merge(source, product, store, language); + } + + @Override + public ReadableProduct merge(Product source, ReadableProduct destination, MerchantStore store, Language language) { + + Validate.notNull(source, "Product cannot be null"); + Validate.notNull(destination, "Product destination cannot be null"); + + + // read only product values + // will contain options + TreeMap selectableOptions = new TreeMap(); + + destination.setSku(source.getSku()); + destination.setRefSku(source.getRefSku()); + destination.setId(source.getId()); + destination.setDateAvailable(DateUtil.formatDate(source.getDateAvailable())); + + ProductDescription description = null; + if (source.getDescriptions() != null && source.getDescriptions().size() > 0) { + for (ProductDescription desc : source.getDescriptions()) { + if (language != null && desc.getLanguage() != null + && desc.getLanguage().getId().intValue() == language.getId().intValue()) { + description = desc; + break; + } + } + } + destination.setId(source.getId()); + destination.setAvailable(source.isAvailable()); + destination.setProductShipeable(source.isProductShipeable()); + + destination.setPreOrder(source.isPreOrder()); + destination.setRefSku(source.getRefSku()); + destination.setSortOrder(source.getSortOrder()); + + if (source.getType() != null) { + ReadableProductType readableType = readableProductTypeMapper.convert(source.getType(), store, language); + destination.setType(readableType); + } + + if (source.getDateAvailable() != null) { + destination.setDateAvailable(DateUtil.formatDate(source.getDateAvailable())); + } + + if (source.getAuditSection() != null) { + destination.setCreationDate(DateUtil.formatDate(source.getAuditSection().getDateCreated())); + } + + destination.setProductVirtual(source.getProductVirtual()); + + if (source.getProductReviewCount() != null) { + destination.setRatingCount(source.getProductReviewCount().intValue()); + } + + if (source.getManufacturer() != null) { + ReadableManufacturer manufacturer = readableManufacturerMapper.convert(source.getManufacturer(), store, + language); + destination.setManufacturer(manufacturer); + } + + // images + Set images = source.getImages(); + if (CollectionUtils.isNotEmpty(images)) { + + List imageList = images.stream().map(i -> this.convertImage(source, i, store)) + .collect(Collectors.toList()); + destination.setImages(imageList); + } + + if (!CollectionUtils.isEmpty(source.getAttributes())) { + + Set attributes = source.getAttributes(); + + if (!CollectionUtils.isEmpty(attributes)) { + + for (ProductAttribute attribute : attributes) { + ReadableProductOption opt = null; + ReadableProductAttribute attr = null; + ReadableProductProperty property = null; + ReadableProductPropertyValue propertyValue = null; + ReadableProductAttributeValue attrValue = new ReadableProductAttributeValue(); + + ProductOptionValue optionValue = attribute.getProductOptionValue(); + + // we need to set readonly attributes only + if (attribute.getAttributeDisplayOnly()) {// read only attribute = property + + property = createProperty(attribute, language); + + ReadableProductOption readableOption = new ReadableProductOption(); // that is the property + ReadableProductPropertyValue readableOptionValue = new ReadableProductPropertyValue(); + + readableOption.setCode(attribute.getProductOption().getCode()); + readableOption.setId(attribute.getProductOption().getId()); + + Set podescriptions = attribute.getProductOption().getDescriptions(); + if (podescriptions != null && podescriptions.size() > 0) { + for (ProductOptionDescription optionDescription : podescriptions) { + if (optionDescription.getLanguage().getCode().equals(language.getCode())) { + readableOption.setName(optionDescription.getName()); + } + } + } + + property.setProperty(readableOption); + + Set povdescriptions = attribute.getProductOptionValue() + .getDescriptions(); + readableOptionValue.setId(attribute.getProductOptionValue().getId()); + readableOptionValue.setCode(optionValue.getCode()); + if (povdescriptions != null && povdescriptions.size() > 0) { + for (ProductOptionValueDescription optionValueDescription : povdescriptions) { + if (optionValueDescription.getLanguage().getCode().equals(language.getCode())) { + readableOptionValue.setName(optionValueDescription.getName()); + } + } + } + + property.setPropertyValue(readableOptionValue); + destination.getProperties().add(property); + + } else {// selectable option + + /** + * Returns a list of ReadableProductOptions + * + * name lang type code List ReadableProductOptionValueEntity name description + * image order default + */ + + if (selectableOptions == null) { + selectableOptions = new TreeMap(); + } + opt = selectableOptions.get(attribute.getProductOption().getId()); + if (opt == null) { + opt = createOption(attribute.getProductOption(), language); + } + if (opt != null) { + selectableOptions.put(attribute.getProductOption().getId(), opt); + } + + ReadableProductOptionValue optValue = new ReadableProductOptionValue(); + + optValue.setDefaultValue(attribute.getAttributeDefault()); + // optValue.setId(attribute.getProductOptionValue().getId()); + optValue.setId(attribute.getId()); + optValue.setCode(attribute.getProductOptionValue().getCode()); + + com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription valueDescription = new com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription(); + valueDescription.setLanguage(language.getCode()); + // optValue.setLang(language.getCode()); + if (attribute.getProductAttributePrice() != null + && attribute.getProductAttributePrice().doubleValue() > 0) { + String formatedPrice = null; + try { + formatedPrice = pricingService.getDisplayAmount(attribute.getProductAttributePrice(), + store); + optValue.setPrice(formatedPrice); + } catch (ServiceException e) { + throw new ConversionRuntimeException( + "Error converting product option, an exception occured with pricingService", e); + } + } + + if (!StringUtils.isBlank(attribute.getProductOptionValue().getProductOptionValueImage())) { + optValue.setImage(imageUtils.buildProductPropertyImageUtils(store, + attribute.getProductOptionValue().getProductOptionValueImage())); + } + optValue.setSortOrder(0); + if (attribute.getProductOptionSortOrder() != null) { + optValue.setSortOrder(attribute.getProductOptionSortOrder().intValue()); + } + + List podescriptions = optionValue.getDescriptionsSettoList(); + ProductOptionValueDescription podescription = null; + if (podescriptions != null && podescriptions.size() > 0) { + podescription = podescriptions.get(0); + if (podescriptions.size() > 1) { + for (ProductOptionValueDescription optionValueDescription : podescriptions) { + if (optionValueDescription.getLanguage().getId().intValue() == language.getId() + .intValue()) { + podescription = optionValueDescription; + break; + } + } + } + } + valueDescription.setName(podescription.getName()); + valueDescription.setDescription(podescription.getDescription()); + optValue.setDescription(valueDescription); + + if (opt != null) { + opt.getOptionValues().add(optValue); + } + } + } + } + } + + ReadableProductVariant defaultInstance = null; + + // variants + if (!CollectionUtils.isEmpty(source.getVariants())) + + { + List instances = source + .getVariants().stream() + .map(i -> readableProductVariantMapper.convert(i, store, language)).collect(Collectors.toList()); + destination.setVariants(instances); + + /** + * When an item has instances + * Take default instance + * + * - Set item price as default instance price + * - Set default image as default instance image + */ + + //get default instance + defaultInstance = instances.stream().filter(i -> i.isDefaultSelection()).findAny().orElse(null); + + + /** + * variants options list variation color + */ + + /** + * Returns a list of ReadableProductOptions + * + * name lang type code List ReadableProductOptionValueEntity name description + * image order default + */ + + /** + * Create options from instance Create a list of option values + */ + + for (ProductVariant instance : source.getVariants()) { + instanceToOption(selectableOptions, instance, store, language); + } + + } + + if (selectableOptions != null) { + List options = new ArrayList(selectableOptions.values()); + destination.setOptions(options); + } + + // availability + ProductAvailability availability = null; + for (ProductAvailability a : source.getAvailabilities()) { + // TODO validate region + // if(availability.getRegion().equals(Constants.ALL_REGIONS)) {//TODO REL 3.X + // accept a region + + /** + * Default availability + * store + * product + * instance null + * region variant null + */ + + + availability = a; + destination.setQuantity(availability.getProductQuantity() == null ? 1 : availability.getProductQuantity()); + destination.setQuantityOrderMaximum( + availability.getProductQuantityOrderMax() == null ? 1 : availability.getProductQuantityOrderMax()); + destination.setQuantityOrderMinimum( + availability.getProductQuantityOrderMin() == null ? 1 : availability.getProductQuantityOrderMin()); + if (availability.getProductQuantity().intValue() > 0 && destination.isAvailable()) { + destination.setCanBePurchased(true); + } + + if(a.getProductVariant()==null && StringUtils.isEmpty(a.getRegionVariant())) { + break; + } + } + + //if default instance + + destination.setSku(source.getSku()); + + try { + FinalPrice price = pricingService.calculateProductPrice(source); + if (price != null) { + + destination.setFinalPrice(pricingService.getDisplayAmount(price.getFinalPrice(), store)); + destination.setPrice(price.getFinalPrice()); + destination.setOriginalPrice(pricingService.getDisplayAmount(price.getOriginalPrice(), store)); + + if (price.isDiscounted()) { + destination.setDiscounted(true); + } + + // price appender + if (availability != null) { + Set prices = availability.getPrices(); + if (!CollectionUtils.isEmpty(prices)) { + ReadableProductPrice readableProductPrice = new ReadableProductPrice(); + readableProductPrice.setDiscounted(destination.isDiscounted()); + readableProductPrice.setFinalPrice(destination.getFinalPrice()); + readableProductPrice.setOriginalPrice(destination.getOriginalPrice()); + + Optional pr = prices.stream() + .filter(p -> p.getCode().equals(ProductPrice.DEFAULT_PRICE_CODE)).findFirst(); + + destination.setProductPrice(readableProductPrice); + + if (pr.isPresent() && language !=null) { + readableProductPrice.setId(pr.get().getId()); + Optional d = pr.get().getDescriptions().stream() + .filter(desc -> desc.getLanguage().getCode().equals(language.getCode())) + .findFirst(); + if (d.isPresent()) { + com.salesmanager.shop.model.catalog.product.ProductPriceDescription priceDescription = new com.salesmanager.shop.model.catalog.product.ProductPriceDescription(); + priceDescription.setLanguage(language.getCode()); + priceDescription.setId(d.get().getId()); + priceDescription.setPriceAppender(d.get().getPriceAppender()); + readableProductPrice.setDescription(priceDescription); + } + } + + } + } + + } + + } catch (Exception e) { + throw new ConversionRuntimeException("An error while converting product price", e); + } + + if (source.getProductReviewAvg() != null) { + double avg = source.getProductReviewAvg().doubleValue(); + double rating = Math.round(avg * 2) / 2.0f; + destination.setRating(rating); + } + + if (source.getProductReviewCount() != null) { + destination.setRatingCount(source.getProductReviewCount().intValue()); + } + + if (description != null) { + com.salesmanager.shop.model.catalog.product.ProductDescription tragetDescription = populateDescription( + description); + destination.setDescription(tragetDescription); + + } + + if (!CollectionUtils.isEmpty(source.getCategories())) { + List categoryList = new ArrayList(); + for (Category category : source.getCategories()) { + ReadableCategory readableCategory = readableCategoryMapper.convert(category, store, language); + categoryList.add(readableCategory); + + } + destination.setCategories(categoryList); + } + + ProductSpecification specifications = new ProductSpecification(); + specifications.setHeight(source.getProductHeight()); + specifications.setLength(source.getProductLength()); + specifications.setWeight(source.getProductWeight()); + specifications.setWidth(source.getProductWidth()); + if (!StringUtils.isBlank(store.getSeizeunitcode())) { + specifications + .setDimensionUnitOfMeasure(DimensionUnitOfMeasure.valueOf(store.getSeizeunitcode().toLowerCase())); + } + if (!StringUtils.isBlank(store.getWeightunitcode())) { + specifications.setWeightUnitOfMeasure(WeightUnitOfMeasure.valueOf(store.getWeightunitcode().toLowerCase())); + } + destination.setProductSpecifications(specifications); + + destination.setSortOrder(source.getSortOrder()); + + return destination; + } + + private ReadableImage convertImage(Product product, ProductImage image, MerchantStore store) { + ReadableImage prdImage = new ReadableImage(); + prdImage.setImageName(image.getProductImage()); + prdImage.setDefaultImage(image.isDefaultImage()); + + // TODO product variant image + StringBuilder imgPath = new StringBuilder(); + imgPath.append(imageUtils.getContextPath()) + .append(imageUtils.buildProductImageUtils(store, product.getSku(), image.getProductImage())); + + prdImage.setImageUrl(imgPath.toString()); + prdImage.setId(image.getId()); + prdImage.setImageType(image.getImageType()); + if (image.getProductImageUrl() != null) { + prdImage.setExternalUrl(image.getProductImageUrl()); + } + if (image.getImageType() == 1 && image.getProductImageUrl() != null) {// video + prdImage.setVideoUrl(image.getProductImageUrl()); + } + + if (prdImage.isDefaultImage()) { + prdImage.setDefaultImage(true); + } + + return prdImage; + } + + private com.salesmanager.shop.model.catalog.product.ProductDescription populateDescription( + ProductDescription description) { + if (description == null) { + return null; + } + + com.salesmanager.shop.model.catalog.product.ProductDescription tragetDescription = new com.salesmanager.shop.model.catalog.product.ProductDescription(); + tragetDescription.setFriendlyUrl(description.getSeUrl()); + tragetDescription.setName(description.getName()); + tragetDescription.setId(description.getId()); + if (!StringUtils.isBlank(description.getMetatagTitle())) { + tragetDescription.setTitle(description.getMetatagTitle()); + } else { + tragetDescription.setTitle(description.getName()); + } + tragetDescription.setMetaDescription(description.getMetatagDescription()); + tragetDescription.setDescription(description.getDescription()); + tragetDescription.setHighlights(description.getProductHighlight()); + tragetDescription.setLanguage(description.getLanguage().getCode()); + tragetDescription.setKeyWords(description.getMetatagKeywords()); + + if (description.getLanguage() != null) { + tragetDescription.setLanguage(description.getLanguage().getCode()); + } + return tragetDescription; + } + + private ReadableProductProperty createProperty(ProductAttribute productAttribute, Language language) { + + ReadableProductProperty attr = new ReadableProductProperty(); + attr.setId(productAttribute.getProductOption().getId());// attribute of the option + attr.setType(productAttribute.getProductOption().getProductOptionType()); + + List descriptions = productAttribute.getProductOption().getDescriptionsSettoList(); + + ReadableProductPropertyValue propertyValue = new ReadableProductPropertyValue(); + + if (descriptions != null && descriptions.size() > 0) { + for (ProductOptionDescription optionDescription : descriptions) { + com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription productOptionValueDescription = new com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription(); + productOptionValueDescription.setId(optionDescription.getId()); + productOptionValueDescription.setLanguage(optionDescription.getLanguage().getCode()); + productOptionValueDescription.setName(optionDescription.getName()); + propertyValue.getValues().add(productOptionValueDescription); + + } + } + + attr.setCode(productAttribute.getProductOption().getCode()); + return attr; + + } + + private Optional optionValue(ProductOptionValue optionValue, MerchantStore store, + Language language) { + + if (optionValue == null) { + return Optional.empty(); + } + + ReadableProductOptionValue optValue = new ReadableProductOptionValue(); + + com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription valueDescription = new com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription(); + valueDescription.setLanguage(language.getCode()); + + if (!StringUtils.isBlank(optionValue.getProductOptionValueImage())) { + optValue.setImage( + imageUtils.buildProductPropertyImageUtils(store, optionValue.getProductOptionValueImage())); + } + optValue.setSortOrder(0); + + if (optionValue.getProductOptionValueSortOrder() != null) { + optValue.setSortOrder(optionValue.getProductOptionValueSortOrder().intValue()); + } + + optValue.setCode(optionValue.getCode()); + + List podescriptions = optionValue.getDescriptionsSettoList(); + ProductOptionValueDescription podescription = null; + if (podescriptions != null && podescriptions.size() > 0) { + podescription = podescriptions.get(0); + if (podescriptions.size() > 1) { + for (ProductOptionValueDescription optionValueDescription : podescriptions) { + if (optionValueDescription.getLanguage().getId().intValue() == language.getId().intValue()) { + podescription = optionValueDescription; + break; + } + } + } + } + valueDescription.setName(podescription.getName()); + valueDescription.setDescription(podescription.getDescription()); + optValue.setDescription(valueDescription); + + return Optional.of(optValue); + + } + + private void instanceToOption(TreeMap selectableOptions, ProductVariant instance, + MerchantStore store, Language language) { + + + ReadableProductOption option = this.option(selectableOptions, instance.getVariation().getProductOption(), language); + option.setVariant(true); + + + // take care of option value + Optional optionOptionValue = this + .optionValue(instance.getVariation().getProductOptionValue(), store, language); + + if (optionOptionValue.isPresent()) { + optionOptionValue.get().setId(instance.getId()); + if (instance.isDefaultSelection()) { + optionOptionValue.get().setDefaultValue(true); + } + addOptionValue(option, optionOptionValue.get()); + + } + + if (instance.getVariationValue() != null) { + ReadableProductOption optionValue = this.option(selectableOptions, instance.getVariationValue().getProductOption(), language); + + // take care of option value + Optional optionValueOptionValue = this + .optionValue(instance.getVariationValue().getProductOptionValue(), store, language); + + + if (optionValueOptionValue.isPresent()) { + optionValueOptionValue.get().setId(instance.getId()); + if (instance.isDefaultSelection()) { + optionValueOptionValue.get().setDefaultValue(true); + } + addOptionValue(optionValue, optionValueOptionValue.get()); + } + + } + + } + + private void addOptionValue(ReadableProductOption option, ReadableProductOptionValue optionValue) { + + ReadableProductOptionValue find = option.getOptionValues().stream() + .filter(optValue -> optValue.getCode()==optionValue.getCode()) + .findAny() + .orElse(null); + + if(find == null) { + option.getOptionValues().add(optionValue); + } + } + + private ReadableProductOption option(TreeMap selectableOptions, ProductOption option, Language language) { + if(selectableOptions.containsKey(option.getId())) { + return selectableOptions.get(option.getId()); + } + + ReadableProductOption readable = this.createOption(option, language); + selectableOptions.put(readable.getId(), readable); + return readable; + } + + private ReadableProductOption createOption(ProductOption opt, Language language) { + + ReadableProductOption option = new ReadableProductOption(); + option.setId(opt.getId());// attribute of the option + option.setType(opt.getProductOptionType()); + option.setCode(opt.getCode()); + List descriptions = opt.getDescriptionsSettoList(); + ProductOptionDescription description = null; + if (descriptions != null && descriptions.size() > 0) { + description = descriptions.get(0); + if (descriptions.size() > 1) { + for (ProductOptionDescription optionDescription : descriptions) { + if (optionDescription.getLanguage().getCode().equals(language.getCode())) { + description = optionDescription; + break; + } + } + } + } + + if (description == null) { + return null; + } + + option.setLang(language.getCode()); + option.setName(description.getName()); + option.setCode(opt.getCode()); + + return option; + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/ReadableProductVariantGroupMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/ReadableProductVariantGroupMapper.java new file mode 100644 index 0000000000..bda0d133cd --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/ReadableProductVariantGroupMapper.java @@ -0,0 +1,99 @@ +package com.salesmanager.shop.mapper.catalog.product; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.catalog.product.variant.ProductVariantImage; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.catalog.product.variant.ProductVariantGroup; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.ReadableImage; +import com.salesmanager.shop.model.catalog.product.product.variant.ReadableProductVariant; +import com.salesmanager.shop.model.catalog.product.product.variantGroup.ReadableProductVariantGroup; +import com.salesmanager.shop.utils.ImageFilePath; + +@Component +public class ReadableProductVariantGroupMapper implements Mapper { + + + @Autowired + private ReadableProductVariantMapper readableProductVariantMapper; + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + @Override + public ReadableProductVariantGroup convert(ProductVariantGroup source, MerchantStore store, Language language) { + Validate.notNull(source, "productVariantGroup cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + return this.merge(source, new ReadableProductVariantGroup(), store, language); + } + + @Override + public ReadableProductVariantGroup merge(ProductVariantGroup source, ReadableProductVariantGroup destination, + MerchantStore store, Language language) { + Validate.notNull(source, "productVariantGroup cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + if(destination == null) { + destination = new ReadableProductVariantGroup(); + } + + destination.setId(source.getId()); + + Set instances = source.getProductVariants(); + destination.setproductVariants(instances.stream().map(i -> this.instance(i, store, language)).collect(Collectors.toList())); + + //image id should be unique in the list + + Map finalList = new HashMap(); + + List originalList = source.getImages().stream() + .map(i -> this.image(finalList, i, store, language)) + .collect(Collectors.toList()); + + + destination.setImages(new ArrayList(finalList.values())); + + return destination; + } + + private ReadableProductVariant instance(ProductVariant instance, MerchantStore store, Language language) { + + return readableProductVariantMapper.convert(instance, store, language); + } + + private ReadableImage image(Map finalList , ProductVariantImage img, MerchantStore store, Language language) { + ReadableImage readable = null; + if(!finalList.containsKey(img.getId())) { + readable = new ReadableImage(); + readable.setId(img.getId()); + readable.setImageName(img.getProductImage()); + readable.setImageUrl(imageUtils.buildCustomTypeImageUtils(store, img.getProductImage(), FileContentType.VARIANT)); + readable.setDefaultImage(img.isDefaultImage()); + finalList.put(img.getId(), readable); + + } + return readable; + + } + +} + + diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/ReadableProductVariantMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/ReadableProductVariantMapper.java new file mode 100644 index 0000000000..711b1f4a66 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/catalog/product/ReadableProductVariantMapper.java @@ -0,0 +1,115 @@ +package com.salesmanager.shop.mapper.catalog.product; + + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import org.apache.commons.collections.CollectionUtils; +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.variant.ProductVariantImage; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.mapper.catalog.ReadableProductVariationMapper; +import com.salesmanager.shop.mapper.inventory.ReadableInventoryMapper; +import com.salesmanager.shop.model.catalog.product.ReadableImage; +import com.salesmanager.shop.model.catalog.product.inventory.ReadableInventory; +import com.salesmanager.shop.model.catalog.product.product.variant.ReadableProductVariant; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.utils.DateUtil; +import com.salesmanager.shop.utils.ImageFilePath; + +@Component +public class ReadableProductVariantMapper implements Mapper { + + + @Autowired + private ReadableProductVariationMapper readableProductVariationMapper; + + @Autowired + private ReadableInventoryMapper readableInventoryMapper; + + @Inject + @Qualifier("img") + private ImageFilePath imagUtils; + + @Override + public ReadableProductVariant convert(ProductVariant source, MerchantStore store, Language language) { + ReadableProductVariant readableproductVariant = new ReadableProductVariant(); + return this.merge(source, readableproductVariant, store, language); + } + + @Override + public ReadableProductVariant merge(ProductVariant source, ReadableProductVariant destination, + MerchantStore store, Language language) { + + Validate.notNull(source, "Product instance cannot be null"); + Validate.notNull(source.getProduct(), "Product cannot be null"); + + if(destination == null) { + destination = new ReadableProductVariant(); + } + + destination.setSortOrder(source.getSortOrder() != null ? source.getSortOrder().intValue():0); + destination.setAvailable(source.isAvailable()); + destination.setDateAvailable(DateUtil.formatDate(source.getDateAvailable())); + destination.setId(source.getId()); + destination.setDefaultSelection(source.isDefaultSelection()); + destination.setProductId(source.getProduct().getId()); + destination.setSku(source.getSku()); + destination.setSortOrder(source.getSortOrder()); + destination.setCode(source.getCode()); + + //get product + Product baseProduct = source.getProduct(); + if(baseProduct == null) { + throw new ResourceNotFoundException("Product instances do not include the parent product [" + destination.getSku() + "]"); + } + + destination.setProductShipeable(baseProduct.isProductShipeable()); + + //destination.setStore(null); + destination.setStore(store.getCode()); + destination.setVariation(readableProductVariationMapper.convert(source.getVariation(), store, language)); + if(source.getVariationValue() != null) { + destination.setVariationValue(readableProductVariationMapper.convert(source.getVariationValue(), store, language)); + } + + if(source.getProductVariantGroup() != null) { + Set nameSet = new HashSet<>(); + List instanceImages = source.getProductVariantGroup().getImages().stream().map(i -> this.image(i, store, language)) + .filter(e -> nameSet.add(e.getImageUrl())) + .collect(Collectors.toList()); + destination.setImages(instanceImages); + } + + if(!CollectionUtils.isEmpty(source.getAvailabilities())) { + List inventories = source.getAvailabilities().stream().map(i -> readableInventoryMapper.convert(i, store, language)).collect(Collectors.toList()); + destination.setInventory(inventories); + } + + return destination; + } + + private ReadableImage image(ProductVariantImage instanceImage, MerchantStore store, Language language) { + ReadableImage img = new ReadableImage(); + img.setDefaultImage(instanceImage.isDefaultImage()); + img.setId(instanceImage.getId()); + img.setImageName(instanceImage.getProductImage()); + img.setImageUrl(imagUtils.buildCustomTypeImageUtils(store, img.getImageName(), FileContentType.VARIANT)); + return img; + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/customer/ReadableCustomerMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/customer/ReadableCustomerMapper.java new file mode 100644 index 0000000000..59e8a97d71 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/customer/ReadableCustomerMapper.java @@ -0,0 +1,158 @@ +package com.salesmanager.shop.mapper.customer; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.customer.attribute.CustomerAttribute; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.user.Group; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.customer.ReadableCustomer; +import com.salesmanager.shop.model.customer.address.Address; +import com.salesmanager.shop.model.customer.attribute.CustomerOptionDescription; +import com.salesmanager.shop.model.customer.attribute.CustomerOptionValueDescription; +import com.salesmanager.shop.model.customer.attribute.ReadableCustomerAttribute; +import com.salesmanager.shop.model.customer.attribute.ReadableCustomerOption; +import com.salesmanager.shop.model.customer.attribute.ReadableCustomerOptionValue; +import com.salesmanager.shop.model.security.ReadableGroup; + +@Component +public class ReadableCustomerMapper implements Mapper { + + @Override + public ReadableCustomer convert(Customer source, MerchantStore store, Language language) { + + ReadableCustomer destination = new ReadableCustomer(); + return this.merge(source, destination, store, language); + } + + @Override + public ReadableCustomer merge(Customer source, ReadableCustomer target, MerchantStore store, + Language language) { + + if(source.getId()!=null && source.getId()>0) { + target.setId(source.getId()); + } + target.setEmailAddress(source.getEmailAddress()); + + if (StringUtils.isNotEmpty(source.getNick())) { + target.setUserName(source.getNick()); + } + + if (source.getDefaultLanguage()!= null) { + target.setLanguage(source.getDefaultLanguage().getCode()); + } + + if (source.getGender()!= null) { + target.setGender(source.getGender().name()); + } + + if (StringUtils.isNotEmpty(source.getProvider())) { + target.setProvider(source.getProvider()); + } + + if(source.getBilling()!=null) { + Address address = new Address(); + address.setAddress(source.getBilling().getAddress()); + address.setCity(source.getBilling().getCity()); + address.setCompany(source.getBilling().getCompany()); + address.setFirstName(source.getBilling().getFirstName()); + address.setLastName(source.getBilling().getLastName()); + address.setPostalCode(source.getBilling().getPostalCode()); + address.setPhone(source.getBilling().getTelephone()); + if(source.getBilling().getCountry()!=null) { + address.setCountry(source.getBilling().getCountry().getIsoCode()); + } + if(source.getBilling().getZone()!=null) { + address.setZone(source.getBilling().getZone().getCode()); + } + if(source.getBilling().getState()!=null) { + address.setStateProvince(source.getBilling().getState()); + } + + target.setFirstName(address.getFirstName()); + target.setLastName(address.getLastName()); + + target.setBilling(address); + } + + if(source.getCustomerReviewAvg() != null) { + target.setRating(source.getCustomerReviewAvg().doubleValue()); + } + + if(source.getCustomerReviewCount() != null) { + target.setRatingCount(source.getCustomerReviewCount().intValue()); + } + + if(source.getDelivery()!=null) { + Address address = new Address(); + address.setCity(source.getDelivery().getCity()); + address.setAddress(source.getDelivery().getAddress()); + address.setCompany(source.getDelivery().getCompany()); + address.setFirstName(source.getDelivery().getFirstName()); + address.setLastName(source.getDelivery().getLastName()); + address.setPostalCode(source.getDelivery().getPostalCode()); + address.setPhone(source.getDelivery().getTelephone()); + if(source.getDelivery().getCountry()!=null) { + address.setCountry(source.getDelivery().getCountry().getIsoCode()); + } + if(source.getDelivery().getZone()!=null) { + address.setZone(source.getDelivery().getZone().getCode()); + } + if(source.getDelivery().getState()!=null) { + address.setStateProvince(source.getDelivery().getState()); + } + + target.setDelivery(address); + } else { + target.setDelivery(target.getBilling()); + } + + if(source.getAttributes()!=null) { + for(CustomerAttribute attribute : source.getAttributes()) { + ReadableCustomerAttribute readableAttribute = new ReadableCustomerAttribute(); + readableAttribute.setId(attribute.getId()); + readableAttribute.setTextValue(attribute.getTextValue()); + ReadableCustomerOption option = new ReadableCustomerOption(); + option.setId(attribute.getCustomerOption().getId()); + option.setCode(attribute.getCustomerOption().getCode()); + + CustomerOptionDescription d = new CustomerOptionDescription(); + d.setDescription(attribute.getCustomerOption().getDescriptionsSettoList().get(0).getDescription()); + d.setName(attribute.getCustomerOption().getDescriptionsSettoList().get(0).getName()); + option.setDescription(d); + + readableAttribute.setCustomerOption(option); + + ReadableCustomerOptionValue optionValue = new ReadableCustomerOptionValue(); + optionValue.setId(attribute.getCustomerOptionValue().getId()); + CustomerOptionValueDescription vd = new CustomerOptionValueDescription(); + vd.setDescription(attribute.getCustomerOptionValue().getDescriptionsSettoList().get(0).getDescription()); + vd.setName(attribute.getCustomerOptionValue().getDescriptionsSettoList().get(0).getName()); + optionValue.setCode(attribute.getCustomerOptionValue().getCode()); + optionValue.setDescription(vd); + + + readableAttribute.setCustomerOptionValue(optionValue); + target.getAttributes().add(readableAttribute); + } + + if(source.getGroups() != null) { + for(Group group : source.getGroups()) { + ReadableGroup readableGroup = new ReadableGroup(); + readableGroup.setId(group.getId().longValue()); + readableGroup.setName(group.getGroupName()); + readableGroup.setType(group.getGroupType().name()); + target.getGroups().add( + readableGroup + ); + } + } + } + + return target; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/inventory/PersistableInventoryMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/inventory/PersistableInventoryMapper.java new file mode 100644 index 0000000000..3c8a0fcf29 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/inventory/PersistableInventoryMapper.java @@ -0,0 +1,256 @@ +package com.salesmanager.shop.mapper.inventory; + +import static com.salesmanager.core.business.utils.NumberUtils.isPositive; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.variant.ProductVariantService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPriceDescription; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.PersistableProductPrice; +import com.salesmanager.shop.model.catalog.product.inventory.PersistableInventory; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.utils.DateUtil; + +@Component +public class PersistableInventoryMapper implements Mapper { + + @Autowired + private LanguageService languageService; + + @Autowired + private ProductVariantService productVariantService; + + @Autowired + private ProductService productService; + + @Override + public ProductAvailability convert(PersistableInventory source, MerchantStore store, Language language) { + ProductAvailability availability = new ProductAvailability(); + availability.setMerchantStore(store); + return merge(source, availability, store, language); + + } + + @Override + public ProductAvailability merge(PersistableInventory source, ProductAvailability destination, MerchantStore store, + Language language) { + Validate.notNull(destination, "Product availability cannot be null"); + + try { + Product product = null; + if(source.getProductId()!= null && source.getProductId().longValue() > 0) { + product = productService.findOne(source.getProductId().longValue(), store); + if(product == null) { + throw new ResourceNotFoundException("Product with id [" + source.getProductId() + "] not found for store [" + store.getCode() + "]"); + } + destination.setProduct(product); + } + + /** + * Merging rules + * + * Create vs update + * - existing product availability + * match product id, instance id, merchant id and region then set exiting id + * + */ + Set existingAvailability = product.getAvailabilities(); + ProductAvailability existing = null; + //determine product availability to be used + if(source.getId() != null && source.getId() >0) { + existing = destination; + } else { + existing = existingAvailability.stream() + .filter(a -> + ( + source.getProductId() != null && (a.getProduct().getId().longValue() == source.getProductId().longValue()) + && + a.getMerchantStore().getId() == store.getId() + && + (source.getVariant() == null && a.getProductVariant() == null) || (a.getProductVariant() != null && source.getVariant()!= null && a.getProductVariant().getId().longValue() == source.getVariant().longValue()) + && + (source.getRegionVariant() == null && a.getRegionVariant() == null) || (a.getRegionVariant() != null && source.getRegionVariant() != null && a.getRegionVariant().equals(source.getRegionVariant())) + )).findAny().orElse(null); + } + if(existing != null) { + if(existing.getMerchantStore().getId() != store.getId()) { + throw new ResourceNotFoundException("Product Inventory with id [" + source.getId() + "] not found for store [" + store.getCode() + "]"); + } + destination = existing; + } + + destination.setProductQuantity(source.getQuantity()); + destination.setProductQuantityOrderMin(source.getProductQuantityOrderMax()); + destination.setProductQuantityOrderMax(source.getProductQuantityOrderMin()); + destination.setAvailable(source.isAvailable()); + destination.setOwner(source.getOwner()); + + String region = getRegion(source); + destination.setRegion(region); + + destination.setRegionVariant(source.getRegionVariant()); + if (StringUtils.isNotBlank(source.getDateAvailable())) { + destination.setProductDateAvailable(DateUtil.getDate(source.getDateAvailable())); + } + + if (source.getVariant() != null && source.getVariant() .longValue()> 0) { + Optional instance = productVariantService.getById(source.getVariant(), store); + if(instance.get() == null) { + throw new ResourceNotFoundException("productVariant with id [" + source.getVariant() + "] not found for store [" + store.getCode() + "]"); + } + destination.setSku(instance.get().getSku()); + destination.setProductVariant(instance.get()); + } + + //merge with existing or replace + List prices = new ArrayList(); + for (PersistableProductPrice priceEntity : source.getPrices()) { + + ProductPrice price = null; + + /** + if (isPositive(priceEntity.getId())) { + price = new ProductPrice(); + price.setId(priceEntity.getId()); + } + **/ + + + + if (destination.getPrices() != null) { + for (ProductPrice pp : destination.getPrices()) { + if (isPositive(priceEntity.getId()) && priceEntity.getId().longValue() == pp.getId().longValue()) { + price = pp; + prices.add(pp); + } else if (pp.isDefaultPrice() && priceEntity.isDefaultPrice()) { + if(price == null) { + price = pp; + } + else { + prices.add(pp); + } + } else { + prices.add(pp); + } + + } + } + + if(price == null) { + price = new ProductPrice(); + } + + prices.add(price); + + price.setProductAvailability(destination); + price.setDefaultPrice(priceEntity.isDefaultPrice()); + price.setProductPriceAmount(priceEntity.getPrice()); + price.setDefaultPrice(priceEntity.isDefaultPrice()); + price.setCode(priceEntity.getCode()); + price.setProductPriceSpecialAmount(priceEntity.getDiscountedPrice()); + + if (Objects.nonNull(priceEntity.getDiscountStartDate())) { + Date startDate = DateUtil.getDate(priceEntity.getDiscountStartDate()); + price.setProductPriceSpecialStartDate(startDate); + } + if (Objects.nonNull(priceEntity.getDiscountEndDate())) { + Date endDate = DateUtil.getDate(priceEntity.getDiscountEndDate()); + price.setProductPriceSpecialEndDate(endDate); + } + + Set descs = getProductPriceDescriptions(price, priceEntity.getDescriptions()); + price.setDescriptions(descs); + + destination.setPrices(new HashSet(prices)); + } + + return destination; + + } catch (ResourceNotFoundException rne) { + throw new ConversionRuntimeException(rne.getErrorCode(), rne.getErrorMessage(), rne); + } catch (Exception e) { + throw new ConversionRuntimeException(e); + } + + } + + private Set getProductPriceDescriptions(ProductPrice price, + List descriptions) + throws ConversionException { + if (CollectionUtils.isEmpty(descriptions)) { + return Collections.emptySet(); + } + Set descs = new HashSet(); + for (com.salesmanager.shop.model.catalog.product.ProductPriceDescription desc : descriptions) { + ProductPriceDescription description = null; + if (CollectionUtils.isNotEmpty(price.getDescriptions())) { + for (ProductPriceDescription d : price.getDescriptions()) { + if (isPositive(desc.getId()) && desc.getId().equals(d.getId())) { + desc.setId(d.getId()); + } + } + } + description = getDescription(desc); + description.setProductPrice(price); + descs.add(description); + } + return descs; + } + + private String getRegion(PersistableInventory source) { + return Optional.ofNullable(source.getRegion()).filter(StringUtils::isNotBlank).orElse(Constants.ALL_REGIONS); + } + + private ProductPriceDescription getDescription( + com.salesmanager.shop.model.catalog.product.ProductPriceDescription desc) throws ConversionException { + ProductPriceDescription target = new ProductPriceDescription(); + target.setDescription(desc.getDescription()); + target.setName(desc.getName()); + target.setTitle(desc.getTitle()); + target.setId(null); + if (isPositive(desc.getId())) { + target.setId(desc.getId()); + } + Language lang = getLanguage(desc); + target.setLanguage(lang); + return target; + + } + + private Language getLanguage(com.salesmanager.shop.model.catalog.product.ProductPriceDescription desc) { + try { + return Optional.ofNullable(languageService.getByCode(desc.getLanguage())) + .orElseThrow(() -> new ConversionRuntimeException( + "Language is null for code " + desc.getLanguage() + " use language ISO code [en, fr ...]")); + } catch (ServiceException e) { + throw new ConversionRuntimeException(e); + } + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/inventory/PersistableProductPriceMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/inventory/PersistableProductPriceMapper.java new file mode 100644 index 0000000000..affa9350fa --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/inventory/PersistableProductPriceMapper.java @@ -0,0 +1,201 @@ +package com.salesmanager.shop.mapper.inventory; + +import static com.salesmanager.core.business.utils.NumberUtils.isPositive; + +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import org.apache.commons.collections4.CollectionUtils; +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.availability.ProductAvailabilityService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPriceDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.PersistableProductPrice; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.utils.DateUtil; + +@Component +public class PersistableProductPriceMapper implements Mapper { + + @Autowired + private LanguageService languageService; + + @Autowired + private ProductService productService; + + @Autowired + private ProductAvailabilityService productAvailabilityService; + + @Override + public ProductPrice convert(PersistableProductPrice source, MerchantStore store, Language language) { + return merge(source, new ProductPrice(), store, language); + } + + @Override + public ProductPrice merge(PersistableProductPrice source, ProductPrice destination, MerchantStore store, + Language language) { + + Validate.notNull(source, "PersistableProductPrice cannot be null"); + Validate.notNull(source.getSku(), "Product sku cannot be null"); + + try { + if (destination == null) { + destination = new ProductPrice(); + } + + destination.setId(source.getId()); + + /** + * Get product availability and verify the existing br-pa-1.0.0 + * + * Cannot have multiple default price for the same product availability Default + * price can be edited but cannot create new default price + */ + + ProductAvailability availability = null; + + if (isPositive(source.getProductAvailabilityId())) { + Optional avail = productAvailabilityService + .getById(source.getProductAvailabilityId(), store); + if (avail.isEmpty()) { + throw new ConversionRuntimeException( + "Product availability with id [" + source.getProductAvailabilityId() + "] was not found"); + } + availability = avail.get(); + + } else { + + // get an existing product availability + List existing = productAvailabilityService.getBySku(source.getSku(), store); + + if (!CollectionUtils.isEmpty(existing)) { + // find default availability + Optional avail = existing.stream() + .filter(a -> a.getRegion() != null && a.getRegion().equals(Constants.ALL_REGIONS)) + .findAny(); + if (avail.isPresent()) { + availability = avail.get(); + + // if default price exist for sku exit + if (source.isDefaultPrice()) { + Optional defaultPrice = availability.getPrices().stream() + .filter(p -> p.isDefaultPrice()).findAny(); + if (defaultPrice.isPresent()) { + //throw new ConversionRuntimeException( + // "Default Price already exist for product with sku [" + source.getSku() + "]"); + destination = defaultPrice.get(); + } + } + } + } + + } + + if (availability == null) { + + com.salesmanager.core.model.catalog.product.Product product = productService.getBySku(source.getSku(), + store, language); + if (product == null) { + throw new ConversionRuntimeException("Product with sku [" + source.getSku() + + "] not found for MerchantStore [" + store.getCode() + "]"); + } + + availability = new ProductAvailability(); + availability.setProduct(product); + availability.setRegion(Constants.ALL_REGIONS); + } + + destination.setProductAvailability(availability); + destination.setDefaultPrice(source.isDefaultPrice()); + destination.setProductPriceAmount(source.getPrice()); + destination.setCode(source.getCode()); + destination.setProductPriceSpecialAmount(source.getDiscountedPrice()); + if (source.getDiscountStartDate() != null) { + Date startDate = DateUtil.getDate(source.getDiscountStartDate()); + + destination.setProductPriceSpecialStartDate(startDate); + } + if (source.getDiscountEndDate() != null) { + Date endDate = DateUtil.getDate(source.getDiscountEndDate()); + + destination.setProductPriceSpecialEndDate(endDate); + } + availability.getPrices().add(destination); + destination.setProductAvailability(availability); + destination.setDescriptions(this.getProductPriceDescriptions(destination, source.getDescriptions(), store)); + + + destination.setDefaultPrice(source.isDefaultPrice()); + + } catch (Exception e) { + + throw new ConversionRuntimeException(e); + } + return destination; + } + + private Set getProductPriceDescriptions(ProductPrice price, + List descriptions, + MerchantStore store) { + if (CollectionUtils.isEmpty(descriptions)) { + return Collections.emptySet(); + } + Set descs = new HashSet(); + for (com.salesmanager.shop.model.catalog.product.ProductPriceDescription desc : descriptions) { + ProductPriceDescription description = null; + if (CollectionUtils.isNotEmpty(price.getDescriptions())) { + for (ProductPriceDescription d : price.getDescriptions()) { + if (isPositive(desc.getId()) && desc.getId().equals(d.getId())) { + desc.setId(d.getId()); + } + } + } + description = getDescription(desc); + description.setProductPrice(price); + descs.add(description); + } + return descs; + } + + private ProductPriceDescription getDescription( + com.salesmanager.shop.model.catalog.product.ProductPriceDescription desc) { + ProductPriceDescription target = new ProductPriceDescription(); + target.setDescription(desc.getDescription()); + target.setName(desc.getName()); + target.setTitle(desc.getTitle()); + target.setId(null); + if (isPositive(desc.getId())) { + target.setId(desc.getId()); + } + Language lang = getLanguage(desc); + target.setLanguage(lang); + return target; + + } + + private Language getLanguage(com.salesmanager.shop.model.catalog.product.ProductPriceDescription desc) { + try { + return Optional.ofNullable(languageService.getByCode(desc.getLanguage())) + .orElseThrow(() -> new ConversionRuntimeException( + "Language is null for code " + desc.getLanguage() + " use language ISO code [en, fr ...]")); + } catch (ServiceException e) { + throw new ConversionRuntimeException(e); + } + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/inventory/ReadableInventoryMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/inventory/ReadableInventoryMapper.java new file mode 100644 index 0000000000..fe3384a3fb --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/inventory/ReadableInventoryMapper.java @@ -0,0 +1,134 @@ +package com.salesmanager.shop.mapper.inventory; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +import org.drools.core.util.StringUtils; +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.product.ReadableProductPrice; +import com.salesmanager.shop.model.catalog.product.inventory.ReadableInventory; +import com.salesmanager.shop.model.store.ReadableMerchantStore; +import com.salesmanager.shop.populator.catalog.ReadableProductPricePopulator; +import com.salesmanager.shop.populator.store.ReadableMerchantStorePopulator; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.utils.DateUtil; + +@Component +public class ReadableInventoryMapper implements Mapper { + + @Autowired + private PricingService pricingService; + + @Autowired + private ReadableMerchantStorePopulator readableMerchantStorePopulator; + + @Override + public ReadableInventory convert(ProductAvailability source, MerchantStore store, Language language) { + ReadableInventory availability = new ReadableInventory(); + return merge(source, availability, store, language); + } + + @Override + public ReadableInventory merge(ProductAvailability source, ReadableInventory destination, MerchantStore store, + Language language) { + Validate.notNull(destination, "Destination Product availability cannot be null"); + Validate.notNull(source, "Source Product availability cannot be null"); + + try { + destination.setQuantity(source.getProductQuantity() != null ? source.getProductQuantity().intValue() : 0); + destination.setProductQuantityOrderMax( + source.getProductQuantityOrderMax() != null ? source.getProductQuantityOrderMax().intValue() : 0); + destination.setProductQuantityOrderMin( + source.getProductQuantityOrderMin() != null ? source.getProductQuantityOrderMin().intValue() : 0); + destination.setOwner(source.getOwner()); + destination.setId(source.getId()); + destination.setRegion(source.getRegion()); + destination.setRegionVariant(source.getRegionVariant()); + destination.setStore(store(store, language)); + if (source.getAvailable() != null) { + if (source.getProductDateAvailable() != null) { + boolean isAfter = LocalDate.parse(DateUtil.getPresentDate()) + .isAfter(LocalDate.parse(DateUtil.formatDate(source.getProductDateAvailable()))); + if (isAfter && source.getAvailable().booleanValue()) { + destination.setAvailable(true); + } + destination.setDateAvailable(DateUtil.formatDate(source.getProductDateAvailable())); + } else { + destination.setAvailable(source.getAvailable().booleanValue()); + } + } + + if (source.getAuditSection() != null) { + if (source.getAuditSection().getDateCreated() != null) { + destination.setCreationDate(DateUtil.formatDate(source.getAuditSection().getDateCreated())); + } + } + + List prices = prices(source, store, language); + destination.setPrices(prices); + + if(!StringUtils.isEmpty(source.getSku())) { + destination.setSku(source.getSku()); + } else { + destination.setSku(source.getProduct().getSku()); + } + + FinalPrice price = null; + //try { + price = pricingService.calculateProductPrice(source); + destination.setPrice(price.getStringPrice()); + //} catch (ServiceException e) { + // throw new ConversionRuntimeException("Unable to get product price", e); + //} + + } catch (Exception e) { + throw new ConversionRuntimeException("Error while converting Inventory", e); + } + + return destination; + } + + private ReadableMerchantStore store(MerchantStore store, Language language) throws ConversionException { + if (language == null) { + language = store.getDefaultLanguage(); + } + /* + * ReadableMerchantStorePopulator populator = new + * ReadableMerchantStorePopulator(); + * populator.setCountryService(countryService); + * populator.setZoneService(zoneService); + */ + return readableMerchantStorePopulator.populate(store, new ReadableMerchantStore(), store, language); + } + + private List prices(ProductAvailability source, MerchantStore store, Language language) + throws ConversionException { + + ReadableProductPricePopulator populator = null; + List prices = new ArrayList(); + + for (ProductPrice price : source.getPrices()) { + + populator = new ReadableProductPricePopulator(); + populator.setPricingService(pricingService); + ReadableProductPrice p = populator.populate(price, new ReadableProductPrice(), store, language); + prices.add(p); + + } + return prices; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/optin/PersistableOptinMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/optin/PersistableOptinMapper.java new file mode 100755 index 0000000000..b39ccd53c2 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/optin/PersistableOptinMapper.java @@ -0,0 +1,30 @@ +package com.salesmanager.shop.mapper.optin; + +import org.springframework.stereotype.Component; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.system.optin.Optin; +import com.salesmanager.core.model.system.optin.OptinType; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.system.PersistableOptin; + +@Component +public class PersistableOptinMapper implements Mapper { + + + @Override + public Optin convert(PersistableOptin source, MerchantStore store, Language language) { + Optin optinEntity = new Optin(); + optinEntity.setCode(source.getCode()); + optinEntity.setDescription(source.getDescription()); + optinEntity.setOptinType(OptinType.valueOf(source.getOptinType())); + optinEntity.setMerchant(store); + return optinEntity; + } + + @Override + public Optin merge(PersistableOptin source, Optin destination, MerchantStore store, + Language language) { + return destination; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/optin/ReadableOptinMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/optin/ReadableOptinMapper.java new file mode 100755 index 0000000000..068b3dd32e --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/optin/ReadableOptinMapper.java @@ -0,0 +1,28 @@ +package com.salesmanager.shop.mapper.optin; + +import org.springframework.stereotype.Component; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.system.optin.Optin; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.system.ReadableOptin; + +@Component +public class ReadableOptinMapper implements Mapper { + + + @Override + public ReadableOptin convert(Optin source, MerchantStore store, Language language) { + ReadableOptin optinEntity = new ReadableOptin(); + optinEntity.setCode(source.getCode()); + optinEntity.setDescription(source.getDescription()); + optinEntity.setOptinType(source.getOptinType().name()); + return optinEntity; + } + + @Override + public ReadableOptin merge(Optin source, ReadableOptin destination, MerchantStore store, + Language language) { + return destination; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/order/ReadableOrderProductMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/order/ReadableOrderProductMapper.java new file mode 100644 index 0000000000..f0bec6f8c1 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/order/ReadableOrderProductMapper.java @@ -0,0 +1,154 @@ +package com.salesmanager.shop.mapper.order; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.orderproduct.OrderProduct; +import com.salesmanager.core.model.order.orderproduct.OrderProductAttribute; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.mapper.catalog.product.ReadableProductMapper; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.model.order.ReadableOrderProduct; +import com.salesmanager.shop.model.order.ReadableOrderProductAttribute; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.utils.ImageFilePath; + +@Component +public class ReadableOrderProductMapper implements Mapper { + + @Autowired + PricingService pricingService; + + @Autowired + ProductService productService; + + @Autowired + ReadableProductMapper readableProductMapper; + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + @Override + public ReadableOrderProduct convert(OrderProduct source, MerchantStore store, Language language) { + ReadableOrderProduct orderProduct = new ReadableOrderProduct(); + return this.merge(source, orderProduct, store, language); + } + + @Override + public ReadableOrderProduct merge(OrderProduct source, ReadableOrderProduct target, MerchantStore store, + Language language) { + + Validate.notNull(source, "OrderProduct cannot be null"); + Validate.notNull(target, "ReadableOrderProduct cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + + target.setId(source.getId()); + target.setOrderedQuantity(source.getProductQuantity()); + try { + target.setPrice(pricingService.getDisplayAmount(source.getOneTimeCharge(), store)); + } catch (Exception e) { + throw new ConversionRuntimeException("Cannot convert price", e); + } + target.setProductName(source.getProductName()); + target.setSku(source.getSku()); + + // subtotal = price * quantity + BigDecimal subTotal = source.getOneTimeCharge(); + subTotal = subTotal.multiply(new BigDecimal(source.getProductQuantity())); + + try { + String subTotalPrice = pricingService.getDisplayAmount(subTotal, store); + target.setSubTotal(subTotalPrice); + } catch (Exception e) { + throw new ConversionRuntimeException("Cannot format price", e); + } + + if (source.getOrderAttributes() != null) { + List attributes = new ArrayList(); + for (OrderProductAttribute attr : source.getOrderAttributes()) { + ReadableOrderProductAttribute readableAttribute = new ReadableOrderProductAttribute(); + try { + String price = pricingService.getDisplayAmount(attr.getProductAttributePrice(), store); + readableAttribute.setAttributePrice(price); + } catch (ServiceException e) { + throw new ConversionRuntimeException("Cannot format price", e); + } + + readableAttribute.setAttributeName(attr.getProductAttributeName()); + readableAttribute.setAttributeValue(attr.getProductAttributeValueName()); + attributes.add(readableAttribute); + } + target.setAttributes(attributes); + } + + String productSku = source.getSku(); + if (!StringUtils.isBlank(productSku)) { + Product product = null; + try { + product = productService.getBySku(productSku, store, language); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + if (product != null) { + + + ReadableProduct productProxy = readableProductMapper.convert(product, store, language); + target.setProduct(productProxy); + + /** + + // TODO autowired + ReadableProductPopulator populator = new ReadableProductPopulator(); + populator.setPricingService(pricingService); + populator.setimageUtils(imageUtils); + + ReadableProduct productProxy; + try { + productProxy = populator.populate(product, new ReadableProduct(), store, language); + target.setProduct(productProxy); + } catch (ConversionException e) { + throw new ConversionRuntimeException("Cannot convert product", e); + } + + Set images = product.getImages(); + ProductImage defaultImage = null; + if (images != null) { + for (ProductImage image : images) { + if (defaultImage == null) { + defaultImage = image; + } + if (image.isDefaultImage()) { + defaultImage = image; + } + } + } + if (defaultImage != null) { + target.setImage(defaultImage.getProductImage()); + } + + **/ + } + } + + return target; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/order/ReadableOrderTotalMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/order/ReadableOrderTotalMapper.java new file mode 100644 index 0000000000..1334d46d7a --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/order/ReadableOrderTotalMapper.java @@ -0,0 +1,74 @@ +package com.salesmanager.shop.mapper.order; + +import java.util.Locale; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.OrderTotal; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.order.total.ReadableOrderTotal; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.utils.LabelUtils; +import com.salesmanager.shop.utils.LocaleUtils; + +@Component +public class ReadableOrderTotalMapper implements Mapper { + + @Autowired + private PricingService pricingService; + + @Autowired + private LabelUtils messages; + + @Override + public ReadableOrderTotal convert(OrderTotal source, MerchantStore store, Language language) { + ReadableOrderTotal destination = new ReadableOrderTotal(); + return this.merge(source, destination, store, language); + } + + @Override + public ReadableOrderTotal merge(OrderTotal source, ReadableOrderTotal target, MerchantStore store, + Language language) { + + Validate.notNull(source, "OrderTotal must not be null"); + Validate.notNull(target, "ReadableTotal must not be null"); + Validate.notNull(store, "MerchantStore must not be null"); + Validate.notNull(language, "Language must not be null"); + + Locale locale = LocaleUtils.getLocale(language); + + try { + + target.setCode(source.getOrderTotalCode()); + target.setId(source.getId()); + target.setModule(source.getModule()); + target.setOrder(source.getSortOrder()); + + target.setTitle(messages.getMessage(source.getOrderTotalCode(), locale, source.getOrderTotalCode())); + target.setText(source.getText()); + + target.setValue(source.getValue()); + target.setTotal(pricingService.getDisplayAmount(source.getValue(), store)); + + if (!StringUtils.isBlank(source.getOrderTotalCode())) { + if (Constants.OT_DISCOUNT_TITLE.equals(source.getOrderTotalCode())) { + target.setDiscounted(true); + } + } + + } catch (Exception e) { + throw new ConversionRuntimeException(e); + } + + return target; + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/tax/PersistableTaxClassMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/tax/PersistableTaxClassMapper.java new file mode 100644 index 0000000000..dc3fd786d3 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/tax/PersistableTaxClassMapper.java @@ -0,0 +1,42 @@ +package com.salesmanager.shop.mapper.tax; + +import org.apache.commons.lang3.Validate; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.tax.taxclass.TaxClass; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.tax.PersistableTaxClass; + +@Component +public class PersistableTaxClassMapper implements Mapper { + + @Override + public TaxClass convert(PersistableTaxClass source, MerchantStore store, Language language) { + Validate.notNull(source, "PersistableTaxClass cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + TaxClass taxClass = new TaxClass(); + taxClass.setMerchantStore(store); + taxClass.setTitle(source.getName()); + taxClass.setId(source.getId()); + return this.merge(source, taxClass, store, language); + } + + @Override + public TaxClass merge(PersistableTaxClass source, TaxClass destination, MerchantStore store, Language language) { + Validate.notNull(source, "PersistableTaxClass cannot be null"); + Validate.notNull(destination, "TaxClass cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + + destination.setCode(source.getCode()); + if(source.getId()!=null && source.getId().longValue() > 0) { + destination.setId(source.getId()); + } + destination.setMerchantStore(store); + destination.setTitle(source.getName()); + + return destination; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/tax/PersistableTaxRateMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/tax/PersistableTaxRateMapper.java new file mode 100644 index 0000000000..e8d0d600a9 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/tax/PersistableTaxRateMapper.java @@ -0,0 +1,121 @@ +package com.salesmanager.shop.mapper.tax; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.services.reference.zone.ZoneService; +import com.salesmanager.core.business.services.tax.TaxClassService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.tax.taxrate.TaxRate; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.tax.PersistableTaxRate; +import com.salesmanager.shop.model.tax.TaxRateDescription; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; + +@Component +public class PersistableTaxRateMapper implements Mapper { + + + @Autowired + private CountryService countryService; + + @Autowired + private ZoneService zoneService; + + @Autowired + private LanguageService languageService; + + @Autowired + private TaxClassService taxClassService; + + @Override + public TaxRate convert(PersistableTaxRate source, MerchantStore store, Language language) { + TaxRate rate = new TaxRate(); + return this.merge(source, rate, store, language); + } + + @Override + public TaxRate merge(PersistableTaxRate source, TaxRate destination, MerchantStore store, Language language) { + Validate.notNull(destination, "destination TaxRate cannot be null"); + Validate.notNull(source, "source TaxRate cannot be null"); + try { + destination.setId(source.getId()); + destination.setCode(source.getCode()); + destination.setTaxPriority(source.getPriority()); + + destination.setCountry(countryService.getByCode(source.getCountry())); + destination.setZone(zoneService.getByCode(source.getZone())); + destination.setStateProvince(source.getZone()); + destination.setMerchantStore(store); + destination.setTaxClass(taxClassService.getByCode(source.getTaxClass(), store)); + destination.setTaxRate(source.getRate()); + this.taxRate(destination, source); + + return destination; + + } catch (Exception e) { + throw new ServiceRuntimeException("An error occured withe creating tax rate",e); + } + + + + + } + + private com.salesmanager.core.model.tax.taxrate.TaxRate taxRate(com.salesmanager.core.model.tax.taxrate.TaxRate destination, PersistableTaxRate source) throws Exception { + //List descriptions = new ArrayList(); + + if(!CollectionUtils.isEmpty(source.getDescriptions())) { + for(TaxRateDescription desc : source.getDescriptions()) { + com.salesmanager.core.model.tax.taxrate.TaxRateDescription description = null; + if(!CollectionUtils.isEmpty(destination.getDescriptions())) { + for(com.salesmanager.core.model.tax.taxrate.TaxRateDescription d : destination.getDescriptions()) { + if(!StringUtils.isBlank(desc.getLanguage()) && desc.getLanguage().equals(d.getLanguage().getCode())) { + d.setDescription(desc.getDescription()); + d.setName(desc.getName()); + d.setTitle(desc.getTitle()); + description = d; + break; + } + } + } + if(description == null) { + description = description(desc); + description.setTaxRate(destination); + destination.getDescriptions().add(description); + } + } + } + + return destination; + + } + + private com.salesmanager.core.model.tax.taxrate.TaxRateDescription description(TaxRateDescription source) throws Exception { + + + Validate.notNull(source.getLanguage(),"description.language should not be null"); + com.salesmanager.core.model.tax.taxrate.TaxRateDescription desc = new com.salesmanager.core.model.tax.taxrate.TaxRateDescription(); + desc.setId(null); + desc.setDescription(source.getDescription()); + desc.setName(source.getName()); + if(source.getId() != null && source.getId().longValue()>0) { + desc.setId(source.getId()); + } + Language lang = languageService.getByCode(source.getLanguage()); + desc.setLanguage(lang); + return desc; + + + + } + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/tax/ReadableTaxClassMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/tax/ReadableTaxClassMapper.java new file mode 100644 index 0000000000..e4c8820a4e --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/tax/ReadableTaxClassMapper.java @@ -0,0 +1,34 @@ +package com.salesmanager.shop.mapper.tax; + +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.tax.taxclass.TaxClass; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.tax.ReadableTaxClass; + +@Component +public class ReadableTaxClassMapper implements Mapper { + + @Override + public ReadableTaxClass convert(TaxClass source, MerchantStore store, Language language) { + ReadableTaxClass taxClass = new ReadableTaxClass(); + taxClass.setId(source.getId()); + taxClass.setCode(source.getCode()); + taxClass.setName(source.getTitle()); + taxClass.setStore(store.getCode()); + return taxClass; + } + + @Override + public ReadableTaxClass merge(TaxClass source, ReadableTaxClass destination, MerchantStore store, + Language language) { + destination.setId(source.getId()); + destination.setCode(source.getCode()); + destination.setName(source.getTitle()); + destination.setStore(store.getCode()); + return destination; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/mapper/tax/ReadableTaxRateMapper.java b/sm-shop/src/main/java/com/salesmanager/shop/mapper/tax/ReadableTaxRateMapper.java new file mode 100644 index 0000000000..c35f9ebcdd --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/mapper/tax/ReadableTaxRateMapper.java @@ -0,0 +1,72 @@ +package com.salesmanager.shop.mapper.tax; + +import java.util.List; +import java.util.Optional; + +import org.apache.commons.lang3.Validate; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.tax.taxrate.TaxRate; +import com.salesmanager.core.model.tax.taxrate.TaxRateDescription; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.tax.ReadableTaxRate; +import com.salesmanager.shop.model.tax.ReadableTaxRateDescription; + +@Component +public class ReadableTaxRateMapper implements Mapper { + + @Override + public ReadableTaxRate convert(TaxRate source, MerchantStore store, Language language) { + ReadableTaxRate taxRate = new ReadableTaxRate(); + return this.merge(source, taxRate, store, language); + + } + + @Override + public ReadableTaxRate merge(TaxRate source, ReadableTaxRate destination, MerchantStore store, + Language language) { + Validate.notNull(destination, "destination TaxRate cannot be null"); + Validate.notNull(source, "source TaxRate cannot be null"); + destination.setId(source.getId()); + destination.setCountry(source.getCountry().getIsoCode()); + destination.setZone(source.getZone().getCode()); + destination.setRate(source.getTaxRate().toString()); + destination.setCode(source.getCode()); + destination.setPriority(source.getTaxPriority()); + Optional description = this.convertDescription(source.getDescriptions(), language); + if(description.isPresent()) { + destination.setDescription(description.get()); + } + return destination; + } + + private Optional convertDescription(List descriptions, Language language) { + Validate.notEmpty(descriptions,"List of TaxRateDescriptions should not be empty"); + + Optional description = descriptions.stream() + .filter(desc -> desc.getLanguage().getCode().equals(language.getCode())).findAny(); + if (description.isPresent()) { + return Optional.of(convertDescription(description.get())); + } else { + return Optional.empty(); + } + + + } + + private ReadableTaxRateDescription convertDescription(TaxRateDescription desc) { + ReadableTaxRateDescription d = new ReadableTaxRateDescription(); + d.setDescription(desc.getDescription()); + d.setName(desc.getName()); + d.setLanguage(desc.getLanguage().getCode()); + d.setDescription(desc.getDescription()); + d.setId(desc.getId()); + d.setTitle(desc.getTitle()); + return d; + } + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/model/shop/ContactForm.java b/sm-shop/src/main/java/com/salesmanager/shop/model/shop/ContactForm.java new file mode 100755 index 0000000000..0fc2a39b0f --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/model/shop/ContactForm.java @@ -0,0 +1,45 @@ +package com.salesmanager.shop.model.shop; + +import javax.validation.constraints.Email; +import javax.validation.constraints.NotEmpty; + +public class ContactForm { + + @NotEmpty + private String name; + @NotEmpty + private String subject; + @Email + private String email; + @NotEmpty + private String comment; + + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + public String getComment() { + return comment; + } + public void setComment(String comment) { + this.comment = comment; + } + + public String getSubject() { + return subject; + } + public void setSubject(String subject) { + this.subject = subject; + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/model/shop/PageInformation.java b/sm-shop/src/main/java/com/salesmanager/shop/model/shop/PageInformation.java new file mode 100755 index 0000000000..808352a978 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/model/shop/PageInformation.java @@ -0,0 +1,49 @@ +package com.salesmanager.shop.model.shop; + +import java.io.Serializable; + +public class PageInformation implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String pageTitle; + private String pageDescription; + private String pageKeywords; + private String pageUrl; + private String pageImageUrl; + + public String getPageTitle() { + return pageTitle; + } + public void setPageTitle(String pageTitle) { + this.pageTitle = pageTitle; + } + public String getPageDescription() { + return pageDescription; + } + public void setPageDescription(String pageDescription) { + this.pageDescription = pageDescription; + } + public String getPageKeywords() { + return pageKeywords; + } + public void setPageKeywords(String pageKeywords) { + this.pageKeywords = pageKeywords; + } + public void setPageUrl(String pageUrl) { + this.pageUrl = pageUrl; + } + public String getPageUrl() { + return pageUrl; + } + + public String getPageImageUrl() { + return pageImageUrl; + } + + public void setPageImageUrl(String pageImageUrl) { + this.pageImageUrl = pageImageUrl; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/PersistableAuditAspect.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/PersistableAuditAspect.java new file mode 100755 index 0000000000..0ebc9d66ba --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/PersistableAuditAspect.java @@ -0,0 +1,60 @@ +package com.salesmanager.shop.populator; + +import java.util.Date; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.Aspect; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; + +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.common.audit.Auditable; + +/** + * Create audit section + * @author carlsamson + * + */ +@Aspect +@Configuration +public class PersistableAuditAspect { + + + private static final Logger LOGGER = LoggerFactory.getLogger(PersistableAuditAspect.class); + + @AfterReturning(value = "execution(* populate(..))", + returning = "result") + public void afterReturning(JoinPoint joinPoint, Object result) { + + try { + if(result instanceof Auditable) { + Auditable entity = (Auditable)result; + AuditSection audit = entity.getAuditSection(); + if(entity.getAuditSection()==null) { + audit = new AuditSection(); + } + audit.setDateModified(new Date()); + + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + if(auth!=null) { + if(auth instanceof UsernamePasswordAuthenticationToken) {//api only is captured + com.salesmanager.shop.store.security.user.JWTUser user = (com.salesmanager.shop.store.security.user.JWTUser)auth.getPrincipal(); + audit.setModifiedBy(user.getUsername()); + } + } + //TODO put in log audit log trail + entity.setAuditSection(audit); + } + } catch (Throwable e) { + LOGGER.error("Error while setting audit values" + e.getMessage()); + } + + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/PersistableCategoryPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/PersistableCategoryPopulator.java new file mode 100755 index 0000000000..7244667ddd --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/PersistableCategoryPopulator.java @@ -0,0 +1,181 @@ +package com.salesmanager.shop.populator.catalog; + +import java.util.HashSet; +import java.util.Set; +import javax.inject.Inject; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.stereotype.Component; +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.catalog.category.CategoryService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.category.CategoryDescription; +import com.salesmanager.shop.model.catalog.category.PersistableCategory; + +@Component +public class PersistableCategoryPopulator extends + AbstractDataPopulator { + + @Inject + private CategoryService categoryService; + @Inject + private LanguageService languageService; + + + public void setCategoryService(CategoryService categoryService) { + this.categoryService = categoryService; + } + + public CategoryService getCategoryService() { + return categoryService; + } + + public void setLanguageService(LanguageService languageService) { + this.languageService = languageService; + } + + public LanguageService getLanguageService() { + return languageService; + } + + + @Override + public Category populate(PersistableCategory source, Category target, + MerchantStore store, Language language) + throws ConversionException { + + try { + + Validate.notNull(target, "Category target cannot be null"); + + +/* Validate.notNull(categoryService, "Requires to set CategoryService"); + Validate.notNull(languageService, "Requires to set LanguageService");*/ + + target.setMerchantStore(store); + target.setCode(source.getCode()); + target.setSortOrder(source.getSortOrder()); + target.setVisible(source.isVisible()); + target.setFeatured(source.isFeatured()); + + //children + if(!CollectionUtils.isEmpty(source.getChildren())) { + //no modifications to children category + } else { + target.getCategories().clear(); + } + + //get parent + + if(source.getParent()==null || (StringUtils.isBlank(source.getParent().getCode())) || source.getParent().getId()==null) { + target.setParent(null); + target.setDepth(0); + target.setLineage(new StringBuilder().append("/").append(source.getId()).append("/").toString()); + } else { + Category parent = null; + if(!StringUtils.isBlank(source.getParent().getCode())) { + parent = categoryService.getByCode(store.getCode(), source.getParent().getCode()); + } else if(source.getParent().getId()!=null) { + parent = categoryService.getById(source.getParent().getId(), store.getId()); + } else { + throw new ConversionException("Category parent needs at least an id or a code for reference"); + } + if(parent !=null && parent.getMerchantStore().getId().intValue()!=store.getId().intValue()) { + throw new ConversionException("Store id does not belong to specified parent id"); + } + + if(parent!=null) { + target.setParent(parent); + + String lineage = parent.getLineage(); + int depth = parent.getDepth(); + + target.setDepth(depth+1); + target.setLineage(new StringBuilder().append(lineage).append(target.getId()).append("/").toString()); + } + + } + + + if(!CollectionUtils.isEmpty(source.getChildren())) { + + for(PersistableCategory cat : source.getChildren()) { + + Category persistCategory = this.populate(cat, new Category(), store, language); + target.getCategories().add(persistCategory); + + } + + } + + + if(!CollectionUtils.isEmpty(source.getDescriptions())) { + Set descriptions = new HashSet(); + if(CollectionUtils.isNotEmpty(target.getDescriptions())) { + for(com.salesmanager.core.model.catalog.category.CategoryDescription description : target.getDescriptions()) { + for(CategoryDescription d : source.getDescriptions()) { + if(StringUtils.isBlank(d.getLanguage())) { + throw new ConversionException("Source category description has no language"); + } + if(d.getLanguage().equals(description.getLanguage().getCode())) { + description.setCategory(target); + description = buildDescription(d, description); + descriptions.add(description); + } + } + } + + } else { + for(CategoryDescription d : source.getDescriptions()) { + com.salesmanager.core.model.catalog.category.CategoryDescription t = new com.salesmanager.core.model.catalog.category.CategoryDescription(); + + this.buildDescription(d, t); + t.setCategory(target); + descriptions.add(t); + + } + + } + target.setDescriptions(descriptions); + } + + + return target; + + + } catch(Exception e) { + throw new ConversionException(e); + } + + } + + private com.salesmanager.core.model.catalog.category.CategoryDescription buildDescription(com.salesmanager.shop.model.catalog.category.CategoryDescription source, com.salesmanager.core.model.catalog.category.CategoryDescription target) throws Exception { + //com.salesmanager.core.model.catalog.category.CategoryDescription desc = new com.salesmanager.core.model.catalog.category.CategoryDescription(); + target.setCategoryHighlight(source.getHighlights()); + target.setDescription(source.getDescription()); + target.setName(source.getName()); + target.setMetatagDescription(source.getMetaDescription()); + target.setMetatagTitle(source.getTitle()); + target.setSeUrl(source.getFriendlyUrl()); + Language lang = languageService.getByCode(source.getLanguage()); + if(lang==null) { + throw new ConversionException("Language is null for code " + source.getLanguage() + " use language ISO code [en, fr ...]"); + } + //description.setId(description.getId()); + target.setLanguage(lang); + return target; + } + + + @Override + protected Category createTarget() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/PersistableProductImagePopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/PersistableProductImagePopulator.java new file mode 100755 index 0000000000..8521cc47d1 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/PersistableProductImagePopulator.java @@ -0,0 +1,52 @@ +package com.salesmanager.shop.populator.catalog; + +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.PersistableImage; + +public class PersistableProductImagePopulator extends AbstractDataPopulator { + + + private Product product; + + @Override + public ProductImage populate(PersistableImage source, ProductImage target, MerchantStore store, Language language) + throws ConversionException { + + Validate.notNull(product,"Must set a product setProduct(Product)"); + Validate.notNull(product.getId(),"Product must have an id not null"); + Validate.notNull(source.getContentType(),"Content type must be set on persistable image"); + + + target.setDefaultImage(source.isDefaultImage()); + target.setImageType(source.getImageType()); + target.setProductImage(source.getName()); + if(source.getImageUrl() != null) { + target.setProductImageUrl(source.getImageUrl()); + } + target.setProduct(product); + + return target; + } + + @Override + protected ProductImage createTarget() { + // TODO Auto-generated method stub + return null; + } + + public Product getProduct() { + return product; + } + + public void setProduct(Product product) { + this.product = product; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/PersistableProductOptionPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/PersistableProductOptionPopulator.java new file mode 100755 index 0000000000..7dc2fbf88b --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/PersistableProductOptionPopulator.java @@ -0,0 +1,78 @@ +package com.salesmanager.shop.populator.catalog; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductOption; +import com.salesmanager.shop.model.catalog.product.attribute.ProductOptionDescription; + + + + +public class PersistableProductOptionPopulator extends + AbstractDataPopulator { + + private LanguageService languageService; + + public LanguageService getLanguageService() { + return languageService; + } + + public void setLanguageService(LanguageService languageService) { + this.languageService = languageService; + } + + @Override + public ProductOption populate(PersistableProductOption source, + ProductOption target, MerchantStore store, Language language) + throws ConversionException { + Validate.notNull(languageService, "Requires to set LanguageService"); + + + try { + + + target.setMerchantStore(store); + target.setProductOptionSortOrder(source.getOrder()); + target.setCode(source.getCode()); + + if(!CollectionUtils.isEmpty(source.getDescriptions())) { + Set descriptions = new HashSet(); + for(ProductOptionDescription desc : source.getDescriptions()) { + com.salesmanager.core.model.catalog.product.attribute.ProductOptionDescription description = new com.salesmanager.core.model.catalog.product.attribute.ProductOptionDescription(); + Language lang = languageService.getByCode(desc.getLanguage()); + if(lang==null) { + throw new ConversionException("Language is null for code " + description.getLanguage() + " use language ISO code [en, fr ...]"); + } + description.setLanguage(lang); + description.setName(desc.getName()); + description.setTitle(desc.getTitle()); + description.setProductOption(target); + descriptions.add(description); + } + target.setDescriptions(descriptions); + } + + } catch (Exception e) { + throw new ConversionException(e); + } + + + return target; + } + + @Override + protected ProductOption createTarget() { + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/PersistableProductOptionValuePopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/PersistableProductOptionValuePopulator.java new file mode 100755 index 0000000000..5bd232c049 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/PersistableProductOptionValuePopulator.java @@ -0,0 +1,85 @@ +package com.salesmanager.shop.populator.catalog; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductOptionValue; +import com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription; + + + +/** + * Converts a PersistableProductOptionValue to + * a ProductOptionValue model object + * @author Carl Samson + * + */ +public class PersistableProductOptionValuePopulator extends + AbstractDataPopulator { + + + private LanguageService languageService; + + public LanguageService getLanguageService() { + return languageService; + } + + public void setLanguageService(LanguageService languageService) { + this.languageService = languageService; + } + + @Override + public ProductOptionValue populate(PersistableProductOptionValue source, + ProductOptionValue target, MerchantStore store, Language language) + throws ConversionException { + + Validate.notNull(languageService, "Requires to set LanguageService"); + + + try { + + + target.setMerchantStore(store); + target.setProductOptionValueSortOrder(source.getOrder()); + target.setCode(source.getCode()); + + if(!CollectionUtils.isEmpty(source.getDescriptions())) { + Set descriptions = new HashSet(); + for(ProductOptionValueDescription desc : source.getDescriptions()) { + com.salesmanager.core.model.catalog.product.attribute.ProductOptionValueDescription description = new com.salesmanager.core.model.catalog.product.attribute.ProductOptionValueDescription(); + Language lang = languageService.getByCode(desc.getLanguage()); + if(lang==null) { + throw new ConversionException("Language is null for code " + description.getLanguage() + " use language ISO code [en, fr ...]"); + } + description.setLanguage(lang); + description.setName(desc.getName()); + description.setTitle(desc.getTitle()); + description.setProductOptionValue(target); + descriptions.add(description); + } + target.setDescriptions(descriptions); + } + + } catch (Exception e) { + throw new ConversionException(e); + } + + + return target; + } + + @Override + protected ProductOptionValue createTarget() { + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/PersistableProductReviewPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/PersistableProductReviewPopulator.java new file mode 100755 index 0000000000..5483b348db --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/PersistableProductReviewPopulator.java @@ -0,0 +1,140 @@ +package com.salesmanager.shop.populator.catalog; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.review.ProductReview; +import com.salesmanager.core.model.catalog.product.review.ProductReviewDescription; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.PersistableProductReview; +import com.salesmanager.shop.utils.DateUtil; + + + +public class PersistableProductReviewPopulator extends + AbstractDataPopulator { + + + + + private CustomerService customerService; + + + private ProductService productService; + + + private LanguageService languageService; + + + + public LanguageService getLanguageService() { + return languageService; + } + + public void setLanguageService(LanguageService languageService) { + this.languageService = languageService; + } + + @Override + public ProductReview populate(PersistableProductReview source, + ProductReview target, MerchantStore store, Language language) + throws ConversionException { + + + Validate.notNull(customerService,"customerService cannot be null"); + Validate.notNull(productService,"productService cannot be null"); + Validate.notNull(languageService,"languageService cannot be null"); + Validate.notNull(source.getRating(),"Rating cannot bot be null"); + + try { + + if(target==null) { + target = new ProductReview(); + } + + Customer customer = customerService.getById(source.getCustomerId()); + + //check if customer belongs to store + if(customer ==null || customer.getMerchantStore().getId().intValue()!=store.getId().intValue()) { + throw new ConversionException("Invalid customer id for the given store"); + } + + if(source.getDate() == null) { + String date = DateUtil.formatDate(new Date()); + source.setDate(date); + } + target.setReviewDate(DateUtil.getDate(source.getDate())); + target.setCustomer(customer); + target.setReviewRating(source.getRating()); + + Product product = productService.getById(source.getProductId()); + + //check if product belongs to store + if(product ==null || product.getMerchantStore().getId().intValue()!=store.getId().intValue()) { + throw new ConversionException("Invalid product id for the given store"); + } + + target.setProduct(product); + + Language lang = languageService.getByCode(language.getCode()); + if(lang ==null) { + throw new ConversionException("Invalid language code, use iso codes (en, fr ...)"); + } + + ProductReviewDescription description = new ProductReviewDescription(); + description.setDescription(source.getDescription()); + description.setLanguage(lang); + description.setName("-"); + description.setProductReview(target); + + Set descriptions = new HashSet(); + descriptions.add(description); + + target.setDescriptions(descriptions); + + + + + + return target; + + } catch (Exception e) { + throw new ConversionException("Cannot populate ProductReview", e); + } + + } + + @Override + protected ProductReview createTarget() { + return null; + } + + public CustomerService getCustomerService() { + return customerService; + } + + public void setCustomerService(CustomerService customerService) { + this.customerService = customerService; + } + + public ProductService getProductService() { + return productService; + } + + public void setProductService(ProductService productService) { + this.productService = productService; + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/ReadableCategoryPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/ReadableCategoryPopulator.java new file mode 100755 index 0000000000..0796e029fe --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/ReadableCategoryPopulator.java @@ -0,0 +1,78 @@ +package com.salesmanager.shop.populator.catalog; + +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.category.CategoryDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.category.ReadableCategory; + +public class ReadableCategoryPopulator extends + AbstractDataPopulator { + + @Override + public ReadableCategory populate(final Category source, + final ReadableCategory target, + final MerchantStore store, + final Language language) throws ConversionException { + + Validate.notNull(source, "Category must not be null"); + + target.setLineage(source.getLineage()); + if (source.getDescriptions() != null && source.getDescriptions().size() > 0) { + + CategoryDescription description = source.getDescription(); + if (source.getDescriptions().size() > 1) { + for (final CategoryDescription desc : source.getDescriptions()) { + if (desc.getLanguage().getCode().equals(language.getCode())) { + description = desc; + break; + } + } + } + + if (description != null) { + final com.salesmanager.shop.model.catalog.category.CategoryDescription desc = new com.salesmanager.shop.model.catalog.category.CategoryDescription(); + desc.setFriendlyUrl(description.getSeUrl()); + desc.setName(description.getName()); + desc.setId(source.getId()); + desc.setDescription(description.getDescription()); + desc.setKeyWords(description.getMetatagKeywords()); + desc.setHighlights(description.getCategoryHighlight()); + desc.setTitle(description.getMetatagTitle()); + desc.setMetaDescription(description.getMetatagDescription()); + + target.setDescription(desc); + } + + } + + if (source.getParent() != null) { + final com.salesmanager.shop.model.catalog.category.Category parent = new com.salesmanager.shop.model.catalog.category.Category(); + parent.setCode(source.getParent().getCode()); + parent.setId(source.getParent().getId()); + target.setParent(parent); + } + + target.setCode(source.getCode()); + target.setId(source.getId()); + if (source.getDepth() != null) { + target.setDepth(source.getDepth()); + } + target.setSortOrder(source.getSortOrder()); + target.setVisible(source.isVisible()); + target.setFeatured(source.isFeatured()); + + return target; + + } + + @Override + protected ReadableCategory createTarget() { + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/ReadableFinalPricePopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/ReadableFinalPricePopulator.java new file mode 100755 index 0000000000..7b21263903 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/ReadableFinalPricePopulator.java @@ -0,0 +1,58 @@ +package com.salesmanager.shop.populator.catalog; + +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.ReadableProductPrice; + +public class ReadableFinalPricePopulator extends + AbstractDataPopulator { + + + private PricingService pricingService; + + public PricingService getPricingService() { + return pricingService; + } + + public void setPricingService(PricingService pricingService) { + this.pricingService = pricingService; + } + + @Override + public ReadableProductPrice populate(FinalPrice source, + ReadableProductPrice target, MerchantStore store, Language language) + throws ConversionException { + Validate.notNull(pricingService,"pricingService must be set"); + + try { + + target.setOriginalPrice(pricingService.getDisplayAmount(source.getOriginalPrice(), store)); + if(source.isDiscounted()) { + target.setDiscounted(true); + target.setFinalPrice(pricingService.getDisplayAmount(source.getDiscountedPrice(), store)); + } else { + target.setFinalPrice(pricingService.getDisplayAmount(source.getFinalPrice(), store)); + } + + } catch(Exception e) { + throw new ConversionException("Exception while converting to ReadableProductPrice",e); + } + + + + return target; + } + + @Override + protected ReadableProductPrice createTarget() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/ReadableProductPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/ReadableProductPopulator.java new file mode 100755 index 0000000000..c53d2a0f6d --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/ReadableProductPopulator.java @@ -0,0 +1,729 @@ +package com.salesmanager.shop.populator.catalog; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.TreeMap; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValueDescription; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.description.ProductDescription; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.catalog.product.manufacturer.ManufacturerDescription; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPriceDescription; +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.category.ReadableCategory; +import com.salesmanager.shop.model.catalog.manufacturer.ReadableManufacturer; +import com.salesmanager.shop.model.catalog.product.ReadableImage; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.model.catalog.product.ReadableProductFull; +import com.salesmanager.shop.model.catalog.product.ReadableProductPrice; +import com.salesmanager.shop.model.catalog.product.RentalOwner; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductAttribute; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductAttributeValue; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductOption; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductProperty; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductPropertyValue; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionValue; +import com.salesmanager.shop.model.catalog.product.product.ProductSpecification; +import com.salesmanager.shop.model.catalog.product.type.ProductTypeDescription; +import com.salesmanager.shop.model.catalog.product.type.ReadableProductType; +import com.salesmanager.shop.utils.DateUtil; +import com.salesmanager.shop.utils.ImageFilePath; + + + +public class ReadableProductPopulator extends + AbstractDataPopulator { + + private PricingService pricingService; + + private ImageFilePath imageUtils; + + public ImageFilePath getimageUtils() { + return imageUtils; + } + + public void setimageUtils(ImageFilePath imageUtils) { + this.imageUtils = imageUtils; + } + + public PricingService getPricingService() { + return pricingService; + } + + public void setPricingService(PricingService pricingService) { + this.pricingService = pricingService; + } + + @Override + public ReadableProduct populate(Product source, + ReadableProduct target, MerchantStore store, Language language) + throws ConversionException { + Validate.notNull(pricingService, "Requires to set PricingService"); + Validate.notNull(imageUtils, "Requires to set imageUtils"); + + + try { + + List fulldescriptions = new ArrayList(); + if(language == null) { + target = new ReadableProductFull(); + } + + if(target==null) { + target = new ReadableProduct(); + } + + ProductDescription description = source.getProductDescription(); + + if(source.getDescriptions()!=null && source.getDescriptions().size()>0) { + for(ProductDescription desc : source.getDescriptions()) { + if(language != null && desc.getLanguage()!=null && desc.getLanguage().getId().intValue() == language.getId().intValue()) { + description = desc; + break; + } else { + fulldescriptions.add(populateDescription(desc)); + } + } + } + + if(target instanceof ReadableProductFull) { + ((ReadableProductFull)target).setDescriptions(fulldescriptions); + } + + if(language == null) { + language = store.getDefaultLanguage(); + } + + final Language lang = language; + + target.setId(source.getId()); + target.setAvailable(source.isAvailable()); + target.setProductShipeable(source.isProductShipeable()); + + ProductSpecification specifications = new ProductSpecification(); + specifications.setHeight(source.getProductHeight()); + specifications.setLength(source.getProductLength()); + specifications.setWeight(source.getProductWeight()); + specifications.setWidth(source.getProductWidth()); + target.setProductSpecifications(specifications); + + target.setPreOrder(source.isPreOrder()); + target.setRefSku(source.getRefSku()); + target.setSortOrder(source.getSortOrder()); + + if(source.getType() != null) { + target.setType(this.type(source.getType(), language)); + } + + if(source.getOwner() != null) { + RentalOwner owner = new RentalOwner(); + owner.setId(source.getOwner().getId()); + owner.setEmailAddress(source.getOwner().getEmailAddress()); + owner.setFirstName(source.getOwner().getBilling().getFirstName()); + owner.setLastName(source.getOwner().getBilling().getLastName()); + com.salesmanager.shop.model.customer.address.Address address = new com.salesmanager.shop.model.customer.address.Address(); + address.setAddress(source.getOwner().getBilling().getAddress()); + address.setBillingAddress(true); + address.setCity(source.getOwner().getBilling().getCity()); + address.setCompany(source.getOwner().getBilling().getCompany()); + address.setCountry(source.getOwner().getBilling().getCountry().getIsoCode()); + address.setZone(source.getOwner().getBilling().getZone().getCode()); + address.setLatitude(source.getOwner().getBilling().getLatitude()); + address.setLongitude(source.getOwner().getBilling().getLongitude()); + address.setPhone(source.getOwner().getBilling().getTelephone()); + address.setPostalCode(source.getOwner().getBilling().getPostalCode()); + owner.setAddress(address); + target.setOwner(owner); + } + + + if(source.getDateAvailable() != null) { + target.setDateAvailable(DateUtil.formatDate(source.getDateAvailable())); + } + + if(source.getAuditSection()!=null) { + target.setCreationDate(DateUtil.formatDate(source.getAuditSection().getDateCreated())); + } + +/* if(source.getProductReviewAvg()!=null) { + double avg = source.getProductReviewAvg().doubleValue(); + double rating = Math.round(avg * 2) / 2.0f; + target.setRating(rating); + }*/ + target.setProductVirtual(source.getProductVirtual()); +/* if(source.getProductReviewCount()!=null) { + target.setRatingCount(source.getProductReviewCount().intValue()); + }*/ + if(description!=null) { + com.salesmanager.shop.model.catalog.product.ProductDescription tragetDescription = populateDescription(description); + target.setDescription(tragetDescription); + + } + + if(source.getManufacturer()!=null) { + ManufacturerDescription manufacturer = source.getManufacturer().getDescriptions().iterator().next(); + ReadableManufacturer manufacturerEntity = new ReadableManufacturer(); + com.salesmanager.shop.model.catalog.manufacturer.ManufacturerDescription d = new com.salesmanager.shop.model.catalog.manufacturer.ManufacturerDescription(); + d.setName(manufacturer.getName()); + manufacturerEntity.setDescription(d); + manufacturerEntity.setId(source.getManufacturer().getId()); + manufacturerEntity.setOrder(source.getManufacturer().getOrder()); + manufacturerEntity.setCode(source.getManufacturer().getCode()); + target.setManufacturer(manufacturerEntity); + } + +/* if(source.getType() != null) { + ReadableProductType type = new ReadableProductType(); + type.setId(source.getType().getId()); + type.setCode(source.getType().getCode()); + type.setName(source.getType().getCode());//need name + target.setType(type); + }*/ + + /** + * TODO use ProductImageMapper + */ + Set images = source.getImages(); + if(images!=null && images.size()>0) { + List imageList = new ArrayList(); + + String contextPath = imageUtils.getContextPath(); + + for(ProductImage img : images) { + ReadableImage prdImage = new ReadableImage(); + prdImage.setImageName(img.getProductImage()); + prdImage.setDefaultImage(img.isDefaultImage()); + prdImage.setOrder(img.getSortOrder() != null ? img.getSortOrder().intValue() : 0); + + if (img.getImageType() == 1 && img.getProductImageUrl()!=null) { + prdImage.setImageUrl(img.getProductImageUrl()); + } else { + StringBuilder imgPath = new StringBuilder(); + imgPath.append(contextPath).append(imageUtils.buildProductImageUtils(store, source.getSku(), img.getProductImage())); + + prdImage.setImageUrl(imgPath.toString()); + } + prdImage.setId(img.getId()); + prdImage.setImageType(img.getImageType()); + if(img.getProductImageUrl()!=null){ + prdImage.setExternalUrl(img.getProductImageUrl()); + } + if(img.getImageType()==1 && img.getProductImageUrl()!=null) {//video + prdImage.setVideoUrl(img.getProductImageUrl()); + } + + if(prdImage.isDefaultImage()) { + target.setImage(prdImage); + } + + imageList.add(prdImage); + } + imageList = imageList.stream() + .sorted(Comparator.comparingInt(ReadableImage::getOrder)) + .collect(Collectors.toList()); + + target + .setImages(imageList); + } + + if(!CollectionUtils.isEmpty(source.getCategories())) { + + ReadableCategoryPopulator categoryPopulator = new ReadableCategoryPopulator(); + List categoryList = new ArrayList(); + + for(Category category : source.getCategories()) { + + ReadableCategory readableCategory = new ReadableCategory(); + categoryPopulator.populate(category, readableCategory, store, language); + categoryList.add(readableCategory); + + } + + target.setCategories(categoryList); + + } + + if(!CollectionUtils.isEmpty(source.getAttributes())) { + + Set attributes = source.getAttributes(); + + + //split read only and options + //Map readOnlyAttributes = null; + Map properties = null; + Map selectableOptions = null; + + if(!CollectionUtils.isEmpty(attributes)) { + + for(ProductAttribute attribute : attributes) { + ReadableProductOption opt = null; + ReadableProductAttribute attr = null; + ReadableProductProperty property = null; + ReadableProductPropertyValue propertyValue = null; + ReadableProductOptionValue optValue = new ReadableProductOptionValue(); + ReadableProductAttributeValue attrValue = new ReadableProductAttributeValue(); + + ProductOptionValue optionValue = attribute.getProductOptionValue(); + + if(attribute.getAttributeDisplayOnly()) {//read only attribute = property + /* + if(readOnlyAttributes==null) { + readOnlyAttributes = new TreeMap(); + } + attr = readOnlyAttributes.get(attribute.getProductOption().getId()); + if(attr==null) { + attr = createAttribute(attribute, language); + } + if(attr!=null) { + readOnlyAttributes.put(attribute.getProductOption().getId(), attr); + } + + + attrValue.setDefaultValue(attribute.getAttributeDefault()); + if(attribute.getProductOptionValue()!=null) { + attrValue.setId(attribute.getProductOptionValue().getId());//id of the option value + } else { + attrValue.setId(attribute.getId()); + } + attrValue.setLang(language.getCode()); + + + attrValue.setSortOrder(0); + if(attribute.getProductOptionSortOrder()!=null) { + attrValue.setSortOrder(attribute.getProductOptionSortOrder().intValue()); + } + + List podescriptions = optionValue.getDescriptionsSettoList(); + ProductOptionValueDescription podescription = null; + if(podescriptions!=null && podescriptions.size()>0) { + podescription = podescriptions.get(0); + if(podescriptions.size()>1) { + for(ProductOptionValueDescription optionValueDescription : podescriptions) { + if(optionValueDescription.getLanguage().getId().intValue()==language.getId().intValue()) { + podescription = optionValueDescription; + break; + } + } + } + } + attrValue.setName(podescription.getName()); + attrValue.setDescription(podescription.getDescription()); + + if(attr!=null) { + attr.getAttributeValues().add(attrValue); + } +*/ + + + //if(properties==null) { + // properties = new TreeMap(); + //} + //property = properties.get(attribute.getProductOption().getId()); + //if(property==null) { + property = createProperty(attribute, language); + + ReadableProductOption readableOption = new ReadableProductOption(); //that is the property + ReadableProductPropertyValue readableOptionValue = new ReadableProductPropertyValue(); + + readableOption.setCode(attribute.getProductOption().getCode()); + readableOption.setId(attribute.getProductOption().getId()); + + Set podescriptions = attribute.getProductOption().getDescriptions(); + if(podescriptions!=null && podescriptions.size()>0) { + for(ProductOptionDescription optionDescription : podescriptions) { + if(optionDescription.getLanguage().getCode().equals(language.getCode())) { + readableOption.setName(optionDescription.getName()); + } + } + } + + property.setProperty(readableOption); + + Set povdescriptions = attribute.getProductOptionValue().getDescriptions(); + readableOptionValue.setId(attribute.getProductOptionValue().getId()); + if(povdescriptions!=null && povdescriptions.size()>0) { + for(ProductOptionValueDescription optionValueDescription : povdescriptions) { + if(optionValueDescription.getLanguage().getCode().equals(language.getCode())) { + readableOptionValue.setName(optionValueDescription.getName()); + } + } + } + + property.setPropertyValue(readableOptionValue); + + + //} else{ + // properties.put(attribute.getProductOption().getId(), property); + //} + +/* propertyValue.setCode(attribute.getProductOptionValue().getCode()); + propertyValue.setId(attribute.getProductOptionValue().getId()); + + + propertyValue.setSortOrder(0); + if(attribute.getProductOptionSortOrder()!=null) { + propertyValue.setSortOrder(attribute.getProductOptionSortOrder().intValue()); + } + + List podescriptions = optionValue.getDescriptionsSettoList(); + if(podescriptions!=null && podescriptions.size()>0) { + for(ProductOptionValueDescription optionValueDescription : podescriptions) { + com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription desc = new com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription(); + desc.setId(optionValueDescription.getId()); + desc.setName(optionValueDescription.getName()); + propertyValue.getValues().add(desc); + } + } + + property.setPropertyValue(propertyValue);*/ + + //if(attr!=null) { + // attr.getAttributeValues().add(attrValue); + //} + target.getProperties().add(property); + + + } else {//selectable option + + if(selectableOptions==null) { + selectableOptions = new TreeMap(); + } + opt = selectableOptions.get(attribute.getProductOption().getId()); + if(opt==null) { + opt = createOption(attribute, language); + } + if(opt!=null) { + selectableOptions.put(attribute.getProductOption().getId(), opt); + } + + optValue.setDefaultValue(attribute.getAttributeDefault()); + //optValue.setId(attribute.getProductOptionValue().getId()); + optValue.setId(attribute.getId()); + optValue.setCode(attribute.getProductOptionValue().getCode()); + com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription valueDescription = new com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription(); + valueDescription.setLanguage(language.getCode()); + //optValue.setLang(language.getCode()); + if(attribute.getProductAttributePrice()!=null && attribute.getProductAttributePrice().doubleValue()>0) { + String formatedPrice = pricingService.getDisplayAmount(attribute.getProductAttributePrice(), store); + optValue.setPrice(formatedPrice); + } + + if(!StringUtils.isBlank(attribute.getProductOptionValue().getProductOptionValueImage())) { + optValue.setImage(imageUtils.buildProductPropertyImageUtils(store, attribute.getProductOptionValue().getProductOptionValueImage())); + } + optValue.setSortOrder(0); + if(attribute.getProductOptionSortOrder()!=null) { + optValue.setSortOrder(attribute.getProductOptionSortOrder().intValue()); + } + + List podescriptions = optionValue.getDescriptionsSettoList(); + ProductOptionValueDescription podescription = null; + if(podescriptions!=null && podescriptions.size()>0) { + podescription = podescriptions.get(0); + if(podescriptions.size()>1) { + for(ProductOptionValueDescription optionValueDescription : podescriptions) { + if(optionValueDescription.getLanguage().getId().intValue()==language.getId().intValue()) { + podescription = optionValueDescription; + break; + } + } + } + } + valueDescription.setName(podescription.getName()); + valueDescription.setDescription(podescription.getDescription()); + optValue.setDescription(valueDescription); + + if(opt!=null) { + opt.getOptionValues().add(optValue); + } + } + + } + + } + + if(selectableOptions != null) { + List options = new ArrayList(selectableOptions.values()); + target.setOptions(options); + } + + + } + + + + //remove products from invisible category -> set visible = false +/* Set categories = source.getCategories(); + boolean isVisible = true; + if(!CollectionUtils.isEmpty(categories)) { + for(Category c : categories) { + if(c.isVisible()) { + isVisible = true; + break; + } else { + isVisible = false; + } + } + }*/ + + //target.setVisible(isVisible); + + //availability + ProductAvailability availability = null; + for(ProductAvailability a : source.getAvailabilities()) { + //TODO validate region + //if(availability.getRegion().equals(Constants.ALL_REGIONS)) {//TODO REL 2.1 accept a region + availability = a; + target.setQuantity(availability.getProductQuantity() == null ? 1:availability.getProductQuantity()); + target.setQuantityOrderMaximum(availability.getProductQuantityOrderMax() == null ? 1:availability.getProductQuantityOrderMax()); + target.setQuantityOrderMinimum(availability.getProductQuantityOrderMin()==null ? 1:availability.getProductQuantityOrderMin()); + if(availability.getProductQuantity().intValue() > 0 && target.isAvailable()) { + target.setCanBePurchased(true); + } + //} + } + + + target.setSku(source.getSku()); + + FinalPrice price = pricingService.calculateProductPrice(source); + + if(price != null) { + + target.setFinalPrice(pricingService.getDisplayAmount(price.getFinalPrice(), store)); + target.setPrice(price.getFinalPrice()); + target.setOriginalPrice(pricingService.getDisplayAmount(price.getOriginalPrice(), store)); + + if(price.isDiscounted()) { + target.setDiscounted(true); + } + + //price appender + if(availability != null) { + Set prices = availability.getPrices(); + if(!CollectionUtils.isEmpty(prices)) { + ReadableProductPrice readableProductPrice = new ReadableProductPrice(); + readableProductPrice.setDiscounted(target.isDiscounted()); + readableProductPrice.setFinalPrice(target.getFinalPrice()); + readableProductPrice.setOriginalPrice(target.getOriginalPrice()); + + Optional pr = prices.stream().filter(p -> p.getCode().equals(ProductPrice.DEFAULT_PRICE_CODE)) + .findFirst(); + + target.setProductPrice(readableProductPrice); + + if(pr.isPresent()) { + readableProductPrice.setId(pr.get().getId()); + Optional d = pr.get().getDescriptions().stream().filter(desc -> desc.getLanguage().getCode().equals(lang.getCode())).findFirst(); + if(d.isPresent()) { + com.salesmanager.shop.model.catalog.product.ProductPriceDescription priceDescription = new com.salesmanager.shop.model.catalog.product.ProductPriceDescription(); + priceDescription.setLanguage(language.getCode()); + priceDescription.setId(d.get().getId()); + priceDescription.setPriceAppender(d.get().getPriceAppender()); + readableProductPrice.setDescription(priceDescription); + } + } + + } + } + + } + + + + + if(target instanceof ReadableProductFull) { + ((ReadableProductFull)target).setDescriptions(fulldescriptions); + } + + + return target; + + } catch (Exception e) { + throw new ConversionException(e); + } + } + + + + private ReadableProductOption createOption(ProductAttribute productAttribute, Language language) { + + + ReadableProductOption option = new ReadableProductOption(); + option.setId(productAttribute.getProductOption().getId());//attribute of the option + option.setType(productAttribute.getProductOption().getProductOptionType()); + option.setCode(productAttribute.getProductOption().getCode()); + List descriptions = productAttribute.getProductOption().getDescriptionsSettoList(); + ProductOptionDescription description = null; + if(descriptions!=null && descriptions.size()>0) { + description = descriptions.get(0); + if(descriptions.size()>1) { + for(ProductOptionDescription optionDescription : descriptions) { + if(optionDescription.getLanguage().getCode().equals(language.getCode())) { + description = optionDescription; + break; + } + } + } + } + + if(description==null) { + return null; + } + + option.setLang(language.getCode()); + option.setName(description.getName()); + option.setCode(productAttribute.getProductOption().getCode()); + + + return option; + + } + + private ReadableProductType type (ProductType type, Language language) { + ReadableProductType readableType = new ReadableProductType(); + readableType.setCode(type.getCode()); + readableType.setId(type.getId()); + + if(!CollectionUtils.isEmpty(type.getDescriptions())) { + Optional desc = type.getDescriptions().stream().filter(t -> t.getLanguage().getCode().equals(language.getCode())) + .map(d -> typeDescription(d)).findFirst(); + if(desc.isPresent()) { + readableType.setDescription(desc.get()); + } + } + + return readableType; + } + + private ProductTypeDescription typeDescription(com.salesmanager.core.model.catalog.product.type.ProductTypeDescription description) { + ProductTypeDescription desc = new ProductTypeDescription(); + desc.setId(description.getId()); + desc.setName(description.getName()); + desc.setDescription(description.getDescription()); + desc.setLanguage(description.getLanguage().getCode()); + return desc; + } + + private ReadableProductAttribute createAttribute(ProductAttribute productAttribute, Language language) { + + + ReadableProductAttribute attr = new ReadableProductAttribute(); + attr.setId(productAttribute.getProductOption().getId());//attribute of the option + attr.setType(productAttribute.getProductOption().getProductOptionType()); + List descriptions = productAttribute.getProductOption().getDescriptionsSettoList(); + ProductOptionDescription description = null; + if(descriptions!=null && descriptions.size()>0) { + description = descriptions.get(0); + if(descriptions.size()>1) { + for(ProductOptionDescription optionDescription : descriptions) { + if(optionDescription.getLanguage().getId().intValue()==language.getId().intValue()) { + description = optionDescription; + break; + } + } + } + } + + if(description==null) { + return null; + } + + attr.setLang(language.getCode()); + attr.setName(description.getName()); + attr.setCode(productAttribute.getProductOption().getCode()); + + + return attr; + + } + + private ReadableProductProperty createProperty(ProductAttribute productAttribute, Language language) { + + + ReadableProductProperty attr = new ReadableProductProperty(); + attr.setId(productAttribute.getProductOption().getId());//attribute of the option + attr.setType(productAttribute.getProductOption().getProductOptionType()); + + + + + List descriptions = productAttribute.getProductOption().getDescriptionsSettoList(); + + ReadableProductPropertyValue propertyValue = new ReadableProductPropertyValue(); + + + if(descriptions!=null && descriptions.size()>0) { + for(ProductOptionDescription optionDescription : descriptions) { + com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription productOptionValueDescription = new com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription(); + productOptionValueDescription.setId(optionDescription.getId()); + productOptionValueDescription.setLanguage(optionDescription.getLanguage().getCode()); + productOptionValueDescription.setName(optionDescription.getName()); + propertyValue.getValues().add(productOptionValueDescription); + + } + } + + attr.setCode(productAttribute.getProductOption().getCode()); + return attr; + + } + + + + + @Override + protected ReadableProduct createTarget() { + // TODO Auto-generated method stub + return null; + } + + com.salesmanager.shop.model.catalog.product.ProductDescription populateDescription(ProductDescription description) { + if(description == null) { + return null; + } + + com.salesmanager.shop.model.catalog.product.ProductDescription tragetDescription = new com.salesmanager.shop.model.catalog.product.ProductDescription(); + tragetDescription.setFriendlyUrl(description.getSeUrl()); + tragetDescription.setName(description.getName()); + tragetDescription.setId(description.getId()); + if(!StringUtils.isBlank(description.getMetatagTitle())) { + tragetDescription.setTitle(description.getMetatagTitle()); + } else { + tragetDescription.setTitle(description.getName()); + } + tragetDescription.setMetaDescription(description.getMetatagDescription()); + tragetDescription.setDescription(description.getDescription()); + tragetDescription.setHighlights(description.getProductHighlight()); + tragetDescription.setLanguage(description.getLanguage().getCode()); + tragetDescription.setKeyWords(description.getMetatagKeywords()); + + if(description.getLanguage() != null) { + tragetDescription.setLanguage(description.getLanguage().getCode()); + } + return tragetDescription; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/ReadableProductPricePopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/ReadableProductPricePopulator.java new file mode 100755 index 0000000000..46488e3864 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/ReadableProductPricePopulator.java @@ -0,0 +1,124 @@ +package com.salesmanager.shop.populator.catalog; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPriceDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.ReadableProductPrice; +import com.salesmanager.shop.model.catalog.product.ReadableProductPriceFull; + + + +public class ReadableProductPricePopulator extends + AbstractDataPopulator { + + + private PricingService pricingService; + + public PricingService getPricingService() { + return pricingService; + } + + public void setPricingService(PricingService pricingService) { + this.pricingService = pricingService; + } + + @Override + public ReadableProductPrice populate(ProductPrice source, + ReadableProductPrice target, MerchantStore store, Language language) + throws ConversionException { + Validate.notNull(pricingService,"pricingService must be set"); + Validate.notNull(source.getProductAvailability(),"productPrice.availability cannot be null"); + Validate.notNull(source.getProductAvailability().getProduct(),"productPrice.availability.product cannot be null"); + + try { + + if(language == null) { + target = new ReadableProductPriceFull(); + } + + if(source.getId() != null && source.getId() > 0) { + target.setId(source.getId()); + } + + target.setDefaultPrice(source.isDefaultPrice()); + + FinalPrice finalPrice = pricingService.calculateProductPrice(source.getProductAvailability().getProduct()); + + target.setOriginalPrice(pricingService.getDisplayAmount(source.getProductPriceAmount(), store)); + if(finalPrice.isDiscounted()) { + target.setDiscounted(true); + target.setFinalPrice(pricingService.getDisplayAmount(source.getProductPriceSpecialAmount(), store)); + } else { + target.setFinalPrice(pricingService.getDisplayAmount(finalPrice.getOriginalPrice(), store)); + } + + if(source.getDescriptions()!=null && source.getDescriptions().size()>0) { + List fulldescriptions = new ArrayList(); + + Set descriptions = source.getDescriptions(); + ProductPriceDescription description = null; + for(ProductPriceDescription desc : descriptions) { + if(language != null && desc.getLanguage().getCode().equals(language.getCode())) { + description = desc; + break; + } else { + fulldescriptions.add(populateDescription(desc)); + } + } + + + if (description != null) { + com.salesmanager.shop.model.catalog.product.ProductPriceDescription d = populateDescription(description); + target.setDescription(d); + } + + if(target instanceof ReadableProductPriceFull) { + ((ReadableProductPriceFull)target).setDescriptions(fulldescriptions); + } + } + + + } catch(Exception e) { + throw new ConversionException("Exception while converting to ReadableProductPrice",e); + } + + + + return target; + } + + @Override + protected ReadableProductPrice createTarget() { + // TODO Auto-generated method stub + return null; + } + + com.salesmanager.shop.model.catalog.product.ProductPriceDescription populateDescription( + ProductPriceDescription description) { + if (description == null) { + return null; + } + com.salesmanager.shop.model.catalog.product.ProductPriceDescription d = + new com.salesmanager.shop.model.catalog.product.ProductPriceDescription(); + d.setName(description.getName()); + d.setDescription(description.getDescription()); + d.setId(description.getId()); + d.setTitle(description.getTitle()); + if (description.getLanguage() != null) { + d.setLanguage(description.getLanguage().getCode()); + } + return d; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/ReadableProductReviewPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/ReadableProductReviewPopulator.java new file mode 100755 index 0000000000..94e01088a6 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/catalog/ReadableProductReviewPopulator.java @@ -0,0 +1,60 @@ +package com.salesmanager.shop.populator.catalog; + +import java.util.Set; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.catalog.product.review.ProductReview; +import com.salesmanager.core.model.catalog.product.review.ProductReviewDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.ReadableProductReview; +import com.salesmanager.shop.model.customer.ReadableCustomer; +import com.salesmanager.shop.populator.customer.ReadableCustomerPopulator; +import com.salesmanager.shop.utils.DateUtil; + +public class ReadableProductReviewPopulator extends + AbstractDataPopulator { + + @Override + public ReadableProductReview populate(ProductReview source, + ReadableProductReview target, MerchantStore store, Language language) + throws ConversionException { + + + try { + ReadableCustomerPopulator populator = new ReadableCustomerPopulator(); + ReadableCustomer customer = new ReadableCustomer(); + populator.populate(source.getCustomer(), customer, store, language); + + target.setId(source.getId()); + target.setDate(DateUtil.formatDate(source.getReviewDate())); + target.setCustomer(customer); + target.setRating(source.getReviewRating()); + target.setProductId(source.getProduct().getId()); + + Set descriptions = source.getDescriptions(); + if(descriptions!=null) { + for(ProductReviewDescription description : descriptions) { + target.setDescription(description.getDescription()); + target.setLanguage(description.getLanguage().getCode()); + break; + } + } + + return target; + + } catch (Exception e) { + throw new ConversionException("Cannot populate ProductReview", e); + } + + + + } + + @Override + protected ReadableProductReview createTarget() { + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/CustomerBillingAddressPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/CustomerBillingAddressPopulator.java new file mode 100755 index 0000000000..bb17a17851 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/CustomerBillingAddressPopulator.java @@ -0,0 +1,53 @@ +/** + * + */ +package com.salesmanager.shop.populator.customer; + + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.customer.address.Address; + +/** + * @author csamson + * + */ +public class CustomerBillingAddressPopulator extends AbstractDataPopulator +{ + + @Override + public Address populate( Customer source, Address target, MerchantStore store, Language language ) + throws ConversionException + { + + target.setCity(source.getBilling().getCity()); + target.setCompany(source.getBilling().getCompany()); + target.setFirstName(source.getBilling().getFirstName()); + target.setLastName(source.getBilling().getLastName()); + target.setPostalCode(source.getBilling().getPostalCode()); + target.setPhone(source.getBilling().getTelephone()); + if(source.getBilling().getTelephone()==null) { + target.setPhone(source.getBilling().getTelephone()); + } + target.setAddress(source.getBilling().getAddress()); + if(source.getBilling().getCountry()!=null) { + target.setCountry(source.getBilling().getCountry().getIsoCode()); + } + if(source.getBilling().getZone()!=null) { + target.setZone(source.getBilling().getZone().getCode()); + } + target.setStateProvince(source.getBilling().getState()); + + return target; + } + + @Override + protected Address createTarget() + { + return new Address(); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/CustomerDeliveryAddressPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/CustomerDeliveryAddressPopulator.java new file mode 100755 index 0000000000..6a803cfb69 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/CustomerDeliveryAddressPopulator.java @@ -0,0 +1,81 @@ +/** + * + */ +package com.salesmanager.shop.populator.customer; + +import org.apache.commons.lang3.StringUtils; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.customer.address.Address; + + + + +/** + * @author Admin + * + */ +public class CustomerDeliveryAddressPopulator extends AbstractDataPopulator +{ + + @Override + public Address populate( Customer source, Address target, MerchantStore store, Language language ) + throws ConversionException + { + + if(source.getDelivery()!=null){ + if(StringUtils.isNotBlank( source.getDelivery().getCity() )){ + target.setCity(source.getDelivery().getCity()); + } + + if(StringUtils.isNotBlank( source.getDelivery().getCompany() )){ + target.setCompany(source.getDelivery().getCompany()); + } + + if(StringUtils.isNotBlank( source.getDelivery().getAddress() )){ + target.setAddress(source.getDelivery().getAddress()); + } + + if(StringUtils.isNotBlank( source.getDelivery().getFirstName() )){ + target.setFirstName(source.getDelivery().getFirstName()); + } + + if(StringUtils.isNotBlank( source.getDelivery().getLastName() )){ + target.setLastName(source.getDelivery().getLastName()); + } + + if(StringUtils.isNotBlank( source.getDelivery().getPostalCode() )){ + target.setPostalCode(source.getDelivery().getPostalCode()); + } + + if(StringUtils.isNotBlank( source.getDelivery().getTelephone() )){ + target.setPhone(source.getDelivery().getTelephone()); + } + + target.setStateProvince(source.getDelivery().getState()); + + if(source.getDelivery().getTelephone()==null) { + target.setPhone(source.getDelivery().getTelephone()); + } + target.setAddress(source.getDelivery().getAddress()); + if(source.getDelivery().getCountry()!=null) { + target.setCountry(source.getDelivery().getCountry().getIsoCode()); + } + if(source.getDelivery().getZone()!=null) { + target.setZone(source.getDelivery().getZone().getCode()); + } + } + return target; + } + + @Override + protected Address createTarget() + { + return new Address(); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/CustomerEntityPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/CustomerEntityPopulator.java new file mode 100755 index 0000000000..4178f85771 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/CustomerEntityPopulator.java @@ -0,0 +1,118 @@ +/** + * + */ +package com.salesmanager.shop.populator.customer; + +import org.apache.commons.lang3.StringUtils; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.customer.CustomerEntity; +import com.salesmanager.shop.model.customer.address.Address; + + + +/** + *

    + * CustomerEntityPopulator will help to populate {@link CustomerEntity} from {@link Customer} CustomerEntity will be + * used to show data on the UI side. + *

    + * + * @author Umesh Awasthi + * @version 1.2 + */ +public class CustomerEntityPopulator + extends AbstractDataPopulator +{ + + @Override + public CustomerEntity populate( final Customer source, final CustomerEntity target, + final MerchantStore merchantStore, final Language language ) + throws ConversionException + { + try + { + + + target.setId( source.getId() ); + if(StringUtils.isNotBlank( source.getEmailAddress() )){ + target.setEmailAddress( source.getEmailAddress() ); + } + + + + if ( source.getBilling() != null ) + { + Address address = new Address(); + address.setCity( source.getBilling().getCity() ); + address.setAddress(source.getBilling().getAddress()); + address.setCompany( source.getBilling().getCompany() ); + address.setFirstName( source.getBilling().getFirstName() ); + address.setLastName( source.getBilling().getLastName() ); + address.setPostalCode( source.getBilling().getPostalCode() ); + address.setPhone( source.getBilling().getTelephone() ); + if ( source.getBilling().getCountry() != null ) + { + address.setCountry( source.getBilling().getCountry().getIsoCode() ); + } + if ( source.getBilling().getZone() != null ) + { + address.setZone( source.getBilling().getZone().getCode() ); + } + + address.setStateProvince(source.getBilling().getState()); + + target.setBilling( address ); + } + + if(source.getCustomerReviewAvg() != null) { + target.setRating(source.getCustomerReviewAvg().doubleValue()); + } + + if(source.getCustomerReviewCount() != null) { + target.setRatingCount(source.getCustomerReviewCount().intValue()); + } + + if ( source.getDelivery() != null ) + { + Address address = new Address(); + address.setCity( source.getDelivery().getCity() ); + address.setAddress(source.getDelivery().getAddress()); + address.setCompany( source.getDelivery().getCompany() ); + address.setFirstName( source.getDelivery().getFirstName() ); + address.setLastName( source.getDelivery().getLastName() ); + address.setPostalCode( source.getDelivery().getPostalCode() ); + address.setPhone( source.getDelivery().getTelephone() ); + if ( source.getDelivery().getCountry() != null ) + { + address.setCountry( source.getDelivery().getCountry().getIsoCode() ); + } + if ( source.getDelivery().getZone() != null ) + { + address.setZone( source.getDelivery().getZone().getCode() ); + } + + address.setStateProvince(source.getDelivery().getState()); + + target.setDelivery( address ); + } + + } + catch ( Exception e ) + { + throw new ConversionException( e ); + } + + return target; + } + + @Override + protected CustomerEntity createTarget() + { + return new CustomerEntity(); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/CustomerOptionPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/CustomerOptionPopulator.java new file mode 100755 index 0000000000..33f35057be --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/CustomerOptionPopulator.java @@ -0,0 +1,75 @@ +package com.salesmanager.shop.populator.customer; + +/** + * Used in the admin section + * @author c.samson + * + */ + +public class CustomerOptionPopulator { + + /** + extends +} + AbstractDataPopulator { + + + private CustomerOptionSet optionSet; + + public CustomerOptionSet getOptionSet() { + return optionSet; + } + + public void setOptionSet(CustomerOptionSet optionSet) { + this.optionSet = optionSet; + } + + @Override + public CustomerOption populate( + com.salesmanager.core.model.customer.attribute.CustomerOption source, + CustomerOption target, MerchantStore store, Language language) throws ConversionException { + + + CustomerOption customerOption = target; + if(customerOption==null) { + customerOption = new CustomerOption(); + } + + customerOption.setId(source.getId()); + customerOption.setType(source.getCustomerOptionType()); + customerOption.setName(source.getDescriptionsSettoList().get(0).getName()); + + List values = customerOption.getAvailableValues(); + if(values==null) { + values = new ArrayList(); + customerOption.setAvailableValues(values); + } + + com.salesmanager.core.model.customer.attribute.CustomerOptionValue optionValue = optionSet.getCustomerOptionValue(); + CustomerOptionValue custOptValue = new CustomerOptionValue(); + custOptValue.setId(optionValue.getId()); + custOptValue.setLanguage(language.getCode()); + custOptValue.setName(optionValue.getDescriptionsSettoList().get(0).getName()); + values.add(custOptValue); + + return customerOption; + + } + + @Override + protected CustomerOption createTarget() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public CustomerOption populate(com.salesmanager.core.model.customer.attribute.CustomerOption source, + CustomerOption target, MerchantStore store, Language language) throws ConversionException { + // TODO Auto-generated method stub + return null; + } + **/ + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/CustomerPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/CustomerPopulator.java new file mode 100755 index 0000000000..a75d9e87ef --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/CustomerPopulator.java @@ -0,0 +1,268 @@ +package com.salesmanager.shop.populator.customer; + + +import java.math.BigDecimal; +import java.util.Map; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.customer.attribute.CustomerOptionService; +import com.salesmanager.core.business.services.customer.attribute.CustomerOptionValueService; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.services.reference.zone.ZoneService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.common.Billing; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.customer.attribute.CustomerAttribute; +import com.salesmanager.core.model.customer.attribute.CustomerOption; +import com.salesmanager.core.model.customer.attribute.CustomerOptionValue; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.shop.model.customer.PersistableCustomer; +import com.salesmanager.shop.model.customer.address.Address; +import com.salesmanager.shop.model.customer.attribute.PersistableCustomerAttribute; + +@Component +public class CustomerPopulator extends + AbstractDataPopulator { + + protected static final Logger LOG=LoggerFactory.getLogger( CustomerPopulator.class ); + @Autowired + private CountryService countryService; + @Autowired + private ZoneService zoneService; + @Autowired + private LanguageService languageService; + @Autowired + private CustomerOptionService customerOptionService; + @Autowired + private CustomerOptionValueService customerOptionValueService; + @Autowired + private PasswordEncoder passwordEncoder; + + + + /** + * Creates a Customer entity ready to be saved + */ + @Override + public Customer populate(PersistableCustomer source, Customer target, + MerchantStore store, Language language) throws ConversionException { + + try { + + if(source.getId() !=null && source.getId()>0){ + target.setId( source.getId() ); + } + + if(!StringUtils.isBlank(source.getPassword())) { + target.setPassword(passwordEncoder.encode(source.getPassword())); + target.setNick(source.getUserName()); + target.setAnonymous(false); + } + + if(source.getBilling() != null) { + target.setBilling(new Billing()); + if (!StringUtils.isEmpty(source.getFirstName())) { + target.getBilling().setFirstName( + source.getFirstName() + ); + } + if (!StringUtils.isEmpty(source.getLastName())) { + target.getBilling().setLastName( + source.getLastName() + ); + } + } + + if(!StringUtils.isBlank(source.getProvider())) { + target.setProvider(source.getProvider()); + } + + if(!StringUtils.isBlank(source.getEmailAddress())) { + target.setEmailAddress(source.getEmailAddress()); + } + + if(source.getGender()!=null && target.getGender()==null) { + target.setGender( com.salesmanager.core.model.customer.CustomerGender.valueOf( source.getGender() ) ); + } + if(target.getGender()==null) { + target.setGender( com.salesmanager.core.model.customer.CustomerGender.M); + } + + Map countries = countryService.getCountriesMap(language); + Map zones = zoneService.getZones(language); + + target.setMerchantStore( store ); + + Address sourceBilling = source.getBilling(); + if(sourceBilling!=null) { + Billing billing = target.getBilling(); + billing.setAddress(sourceBilling.getAddress()); + billing.setCity(sourceBilling.getCity()); + billing.setCompany(sourceBilling.getCompany()); + //billing.setCountry(country); + if (!StringUtils.isEmpty(sourceBilling.getFirstName())) + billing.setFirstName(sourceBilling.getFirstName()); + if (!StringUtils.isEmpty(sourceBilling.getLastName())) + billing.setLastName(sourceBilling.getLastName()); + billing.setTelephone(sourceBilling.getPhone()); + billing.setPostalCode(sourceBilling.getPostalCode()); + billing.setState(sourceBilling.getStateProvince()); + Country billingCountry = null; + if(!StringUtils.isBlank(sourceBilling.getCountry())) { + billingCountry = countries.get(sourceBilling.getCountry()); + if(billingCountry==null) { + throw new ConversionException("Unsuported country code " + sourceBilling.getCountry()); + } + billing.setCountry(billingCountry); + } + + if(billingCountry!=null && !StringUtils.isBlank(sourceBilling.getZone())) { + Zone zone = zoneService.getByCode(sourceBilling.getZone()); + if(zone==null) { + throw new ConversionException("Unsuported zone code " + sourceBilling.getZone()); + } + Zone zoneDescription = zones.get(zone.getCode()); + billing.setZone(zoneDescription); + } + // target.setBilling(billing); + + } + if(target.getBilling() ==null && source.getBilling()!=null){ + LOG.info( "Setting default values for billing" ); + Billing billing = new Billing(); + Country billingCountry = null; + if(StringUtils.isNotBlank( source.getBilling().getCountry() )) { + billingCountry = countries.get(source.getBilling().getCountry()); + if(billingCountry==null) { + throw new ConversionException("Unsuported country code " + sourceBilling.getCountry()); + } + billing.setCountry(billingCountry); + target.setBilling( billing ); + } + } + Address sourceShipping = source.getDelivery(); + if(sourceShipping!=null) { + Delivery delivery = new Delivery(); + delivery.setAddress(sourceShipping.getAddress()); + delivery.setCity(sourceShipping.getCity()); + delivery.setCompany(sourceShipping.getCompany()); + delivery.setFirstName(sourceShipping.getFirstName()); + delivery.setLastName(sourceShipping.getLastName()); + delivery.setTelephone(sourceShipping.getPhone()); + delivery.setPostalCode(sourceShipping.getPostalCode()); + delivery.setState(sourceShipping.getStateProvince()); + Country deliveryCountry = null; + + + + if(!StringUtils.isBlank(sourceShipping.getCountry())) { + deliveryCountry = countries.get(sourceShipping.getCountry()); + if(deliveryCountry==null) { + throw new ConversionException("Unsuported country code " + sourceShipping.getCountry()); + } + delivery.setCountry(deliveryCountry); + } + + if(deliveryCountry!=null && !StringUtils.isBlank(sourceShipping.getZone())) { + Zone zone = zoneService.getByCode(sourceShipping.getZone()); + if(zone==null) { + throw new ConversionException("Unsuported zone code " + sourceShipping.getZone()); + } + Zone zoneDescription = zones.get(zone.getCode()); + delivery.setZone(zoneDescription); + } + target.setDelivery(delivery); + } + + if(source.getRating() != null && source.getRating().doubleValue() > 0) { + target.setCustomerReviewAvg(new BigDecimal(source.getRating().doubleValue())); + } + + if(source.getRatingCount() > 0) { + target.setCustomerReviewCount(source.getRatingCount()); + } + + + if(target.getDelivery() ==null && source.getDelivery()!=null){ + LOG.info( "Setting default value for delivery" ); + Delivery delivery = new Delivery(); + Country deliveryCountry = null; + if(StringUtils.isNotBlank( source.getDelivery().getCountry() )) { + deliveryCountry = countries.get(source.getDelivery().getCountry()); + if(deliveryCountry==null) { + throw new ConversionException("Unsuported country code " + sourceShipping.getCountry()); + } + delivery.setCountry(deliveryCountry); + target.setDelivery( delivery ); + } + } + + if(source.getAttributes()!=null) { + for(PersistableCustomerAttribute attr : source.getAttributes()) { + + CustomerOption customerOption = customerOptionService.getById(attr.getCustomerOption().getId()); + if(customerOption==null) { + throw new ConversionException("Customer option id " + attr.getCustomerOption().getId() + " does not exist"); + } + + CustomerOptionValue customerOptionValue = customerOptionValueService.getById(attr.getCustomerOptionValue().getId()); + if(customerOptionValue==null) { + throw new ConversionException("Customer option value id " + attr.getCustomerOptionValue().getId() + " does not exist"); + } + + if(customerOption.getMerchantStore().getId().intValue()!=store.getId().intValue()) { + throw new ConversionException("Invalid customer option id "); + } + + if(customerOptionValue.getMerchantStore().getId().intValue()!=store.getId().intValue()) { + throw new ConversionException("Invalid customer option value id "); + } + + CustomerAttribute attribute = new CustomerAttribute(); + attribute.setCustomer(target); + attribute.setCustomerOption(customerOption); + attribute.setCustomerOptionValue(customerOptionValue); + attribute.setTextValue(attr.getTextValue()); + + target.getAttributes().add(attribute); + + } + } + + if(target.getDefaultLanguage()==null) { + + Language lang = source.getLanguage() == null ? + language : languageService.getByCode(source.getLanguage()); + + + target.setDefaultLanguage(lang); + } + + + } catch (Exception e) { + throw new ConversionException(e); + } + + + + + return target; + } + + @Override + protected Customer createTarget() { + return new Customer(); + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerBillingAddressPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerBillingAddressPopulator.java new file mode 100755 index 0000000000..67041873c4 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerBillingAddressPopulator.java @@ -0,0 +1,62 @@ +package com.salesmanager.shop.populator.customer; + +import org.apache.commons.lang3.StringUtils; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.customer.address.Address; + +public class PersistableCustomerBillingAddressPopulator extends AbstractDataPopulator +{ + + @Override + public Customer populate( Address source, Customer target, MerchantStore store, Language language ) + throws ConversionException + { + + + target.getBilling().setFirstName( source.getFirstName() ); + target.getBilling().setLastName( source.getLastName() ); + + // lets fill optional data now + + if(StringUtils.isNotBlank( source.getAddress())){ + target.getBilling().setAddress( source.getAddress() ); + } + + if(StringUtils.isNotBlank( source.getCity())){ + target.getBilling().setCity( source.getCity() ); + } + + if(StringUtils.isNotBlank( source.getCompany())){ + target.getBilling().setCompany( source.getCompany() ); + } + + if(StringUtils.isNotBlank( source.getPhone())){ + target.getBilling().setTelephone( source.getPhone()); + } + + if(StringUtils.isNotBlank( source.getPostalCode())){ + target.getBilling().setPostalCode( source.getPostalCode()); + } + + if(StringUtils.isNotBlank( source.getStateProvince())){ + target.getBilling().setState(source.getStateProvince()); + } + + return target; + + } + + @Override + protected Customer createTarget() + { + return null; + } + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerOptionPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerOptionPopulator.java new file mode 100755 index 0000000000..c10318772b --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerOptionPopulator.java @@ -0,0 +1,82 @@ +package com.salesmanager.shop.populator.customer; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.customer.attribute.CustomerOption; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.customer.attribute.CustomerOptionDescription; +import com.salesmanager.shop.model.customer.attribute.PersistableCustomerOption; + +public class PersistableCustomerOptionPopulator extends + AbstractDataPopulator { + + + private LanguageService languageService; + + @Override + public CustomerOption populate(PersistableCustomerOption source, + CustomerOption target, MerchantStore store, Language language) + throws ConversionException { + + + Validate.notNull(languageService, "Requires to set LanguageService"); + + + try { + + target.setCode(source.getCode()); + target.setMerchantStore(store); + target.setSortOrder(source.getOrder()); + if(!StringUtils.isBlank(source.getType())) { + target.setCustomerOptionType(source.getType()); + } else { + target.setCustomerOptionType("TEXT"); + } + target.setPublicOption(true); + + if(!CollectionUtils.isEmpty(source.getDescriptions())) { + Set descriptions = new HashSet(); + for(CustomerOptionDescription desc : source.getDescriptions()) { + com.salesmanager.core.model.customer.attribute.CustomerOptionDescription description = new com.salesmanager.core.model.customer.attribute.CustomerOptionDescription(); + Language lang = languageService.getByCode(desc.getLanguage()); + if(lang==null) { + throw new ConversionException("Language is null for code " + description.getLanguage() + " use language ISO code [en, fr ...]"); + } + description.setLanguage(lang); + description.setName(desc.getName()); + description.setTitle(desc.getTitle()); + description.setCustomerOption(target); + descriptions.add(description); + } + target.setDescriptions(descriptions); + } + + } catch (Exception e) { + throw new ConversionException(e); + } + return target; + } + + @Override + protected CustomerOption createTarget() { + return null; + } + + public void setLanguageService(LanguageService languageService) { + this.languageService = languageService; + } + + public LanguageService getLanguageService() { + return languageService; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerOptionValuePopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerOptionValuePopulator.java new file mode 100755 index 0000000000..2b8a237bdf --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerOptionValuePopulator.java @@ -0,0 +1,75 @@ +package com.salesmanager.shop.populator.customer; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.customer.attribute.CustomerOptionValue; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.customer.attribute.CustomerOptionValueDescription; +import com.salesmanager.shop.model.customer.attribute.PersistableCustomerOptionValue; + +public class PersistableCustomerOptionValuePopulator extends + AbstractDataPopulator { + + + private LanguageService languageService; + + @Override + public CustomerOptionValue populate(PersistableCustomerOptionValue source, + CustomerOptionValue target, MerchantStore store, Language language) + throws ConversionException { + + + Validate.notNull(languageService, "Requires to set LanguageService"); + + + try { + + target.setCode(source.getCode()); + target.setMerchantStore(store); + target.setSortOrder(source.getOrder()); + + if(!CollectionUtils.isEmpty(source.getDescriptions())) { + Set descriptions = new HashSet(); + for(CustomerOptionValueDescription desc : source.getDescriptions()) { + com.salesmanager.core.model.customer.attribute.CustomerOptionValueDescription description = new com.salesmanager.core.model.customer.attribute.CustomerOptionValueDescription(); + Language lang = languageService.getByCode(desc.getLanguage()); + if(lang==null) { + throw new ConversionException("Language is null for code " + description.getLanguage() + " use language ISO code [en, fr ...]"); + } + description.setLanguage(lang); + description.setName(desc.getName()); + description.setTitle(desc.getTitle()); + description.setCustomerOptionValue(target); + descriptions.add(description); + } + target.setDescriptions(descriptions); + } + + } catch (Exception e) { + throw new ConversionException(e); + } + return target; + } + + @Override + protected CustomerOptionValue createTarget() { + return null; + } + + public void setLanguageService(LanguageService languageService) { + this.languageService = languageService; + } + + public LanguageService getLanguageService() { + return languageService; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerPopulator.java new file mode 100755 index 0000000000..982d6ace8c --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerPopulator.java @@ -0,0 +1,112 @@ +package com.salesmanager.shop.populator.customer; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.customer.PersistableCustomer; +import com.salesmanager.shop.model.customer.address.Address; + +public class PersistableCustomerPopulator extends + AbstractDataPopulator { + + @Override + public PersistableCustomer populate(Customer source, + PersistableCustomer target, MerchantStore store, Language language) + throws ConversionException { + + + try { + + + if(source.getBilling()!=null) { + Address address = new Address(); + address.setCity(source.getBilling().getCity()); + address.setCompany(source.getBilling().getCompany()); + address.setFirstName(source.getBilling().getFirstName()); + address.setLastName(source.getBilling().getLastName()); + address.setPostalCode(source.getBilling().getPostalCode()); + address.setPhone(source.getBilling().getTelephone()); + if(source.getBilling().getTelephone()==null) { + address.setPhone(source.getBilling().getTelephone()); + } + address.setAddress(source.getBilling().getAddress()); + if(source.getBilling().getCountry()!=null) { + address.setCountry(source.getBilling().getCountry().getIsoCode()); + } + if(source.getBilling().getZone()!=null) { + address.setZone(source.getBilling().getZone().getCode()); + } + if(source.getBilling().getState()!=null) { + address.setStateProvince(source.getBilling().getState()); + } + + target.setBilling(address); + } + + target.setProvider(source.getProvider()); + + if(source.getCustomerReviewAvg() != null) { + target.setRating(source.getCustomerReviewAvg().doubleValue()); + } + + if(source.getCustomerReviewCount() != null) { + target.setRatingCount(source.getCustomerReviewCount().intValue()); + } + + if(source.getDelivery()!=null) { + Address address = new Address(); + address.setAddress(source.getDelivery().getAddress()); + address.setCity(source.getDelivery().getCity()); + address.setCompany(source.getDelivery().getCompany()); + address.setFirstName(source.getDelivery().getFirstName()); + address.setLastName(source.getDelivery().getLastName()); + address.setPostalCode(source.getDelivery().getPostalCode()); + address.setPhone(source.getDelivery().getTelephone()); + if(source.getDelivery().getCountry()!=null) { + address.setCountry(source.getDelivery().getCountry().getIsoCode()); + } + if(source.getDelivery().getZone()!=null) { + address.setZone(source.getDelivery().getZone().getCode()); + } + if(source.getDelivery().getState()!=null) { + address.setStateProvince(source.getDelivery().getState()); + } + + target.setDelivery(address); + } + + target.setId(source.getId()); + target.setEmailAddress(source.getEmailAddress()); + if(source.getGender()!=null) { + target.setGender(source.getGender().name()); + } + if(source.getDefaultLanguage()!=null) { + target.setLanguage(source.getDefaultLanguage().getCode()); + } + target.setUserName(source.getNick()); + target.setStoreCode(store.getCode()); + if(source.getDefaultLanguage()!=null) { + target.setLanguage(source.getDefaultLanguage().getCode()); + } else { + target.setLanguage(store.getDefaultLanguage().getCode()); + } + + + + } catch (Exception e) { + throw new ConversionException(e); + } + + return target; + + } + + @Override + protected PersistableCustomer createTarget() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerReviewPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerReviewPopulator.java new file mode 100755 index 0000000000..492913bce0 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerReviewPopulator.java @@ -0,0 +1,108 @@ +package com.salesmanager.shop.populator.customer; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.customer.review.CustomerReview; +import com.salesmanager.core.model.customer.review.CustomerReviewDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.customer.PersistableCustomerReview; +import com.salesmanager.shop.utils.DateUtil; + +public class PersistableCustomerReviewPopulator extends AbstractDataPopulator { + + private CustomerService customerService; + + private LanguageService languageService; + + public LanguageService getLanguageService() { + return languageService; + } + + public void setLanguageService(LanguageService languageService) { + this.languageService = languageService; + } + + @Override + public CustomerReview populate(PersistableCustomerReview source, CustomerReview target, MerchantStore store, + Language language) throws ConversionException { + + Validate.notNull(customerService,"customerService cannot be null"); + Validate.notNull(languageService,"languageService cannot be null"); + Validate.notNull(source.getRating(),"Rating cannot bot be null"); + + try { + + if(target==null) { + target = new CustomerReview(); + } + + if(source.getDate() == null) { + String date = DateUtil.formatDate(new Date()); + source.setDate(date); + } + target.setReviewDate(DateUtil.getDate(source.getDate())); + + if(source.getId() != null && source.getId().longValue()==0) { + source.setId(null); + } else { + target.setId(source.getId()); + } + + + Customer reviewer = customerService.getById(source.getCustomerId()); + Customer reviewed = customerService.getById(source.getReviewedCustomer()); + + target.setReviewRating(source.getRating()); + + target.setCustomer(reviewer); + target.setReviewedCustomer(reviewed); + + Language lang = languageService.getByCode(language.getCode()); + if(lang ==null) { + throw new ConversionException("Invalid language code, use iso codes (en, fr ...)"); + } + + CustomerReviewDescription description = new CustomerReviewDescription(); + description.setDescription(source.getDescription()); + description.setLanguage(lang); + description.setName("-"); + description.setCustomerReview(target); + + Set descriptions = new HashSet(); + descriptions.add(description); + + target.setDescriptions(descriptions); + + } catch (Exception e) { + throw new ConversionException("Cannot populate CustomerReview", e); + } + + + return target; + } + + @Override + protected CustomerReview createTarget() { + // TODO Auto-generated method stub + return null; + } + + public CustomerService getCustomerService() { + return customerService; + } + + public void setCustomerService(CustomerService customerService) { + this.customerService = customerService; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerShippingAddressPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerShippingAddressPopulator.java new file mode 100755 index 0000000000..6badd0f615 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/PersistableCustomerShippingAddressPopulator.java @@ -0,0 +1,97 @@ +package com.salesmanager.shop.populator.customer; + +import org.apache.commons.lang3.StringUtils; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.customer.address.Address; + +public class PersistableCustomerShippingAddressPopulator extends AbstractDataPopulator +{ + + @Override + public Customer populate( Address source, Customer target, MerchantStore store, Language language ) + throws ConversionException + { + + + if( target.getDelivery() == null){ + + Delivery delivery=new Delivery(); + delivery.setFirstName( source.getFirstName()) ; + delivery.setLastName( source.getLastName() ); + + if(StringUtils.isNotBlank( source.getAddress())){ + delivery.setAddress( source.getAddress() ); + } + + if(StringUtils.isNotBlank( source.getCity())){ + delivery.setCity( source.getCity() ); + } + + if(StringUtils.isNotBlank( source.getCompany())){ + delivery.setCompany( source.getCompany() ); + } + + if(StringUtils.isNotBlank( source.getPhone())){ + delivery.setTelephone( source.getPhone()); + } + + if(StringUtils.isNotBlank( source.getPostalCode())){ + delivery.setPostalCode( source.getPostalCode()); + } + + if(StringUtils.isNotBlank( source.getStateProvince())){ + delivery.setPostalCode( source.getStateProvince()); + } + + target.setDelivery( delivery ); + } + else{ + target.getDelivery().setFirstName( source.getFirstName() ); + target.getDelivery().setLastName( source.getLastName() ); + + // lets fill optional data now + + if(StringUtils.isNotBlank( source.getAddress())){ + target.getDelivery().setAddress( source.getAddress() ); + } + + if(StringUtils.isNotBlank( source.getCity())){ + target.getDelivery().setCity( source.getCity() ); + } + + if(StringUtils.isNotBlank( source.getCompany())){ + target.getDelivery().setCompany( source.getCompany() ); + } + + if(StringUtils.isNotBlank( source.getPhone())){ + target.getDelivery().setTelephone( source.getPhone()); + } + + if(StringUtils.isNotBlank( source.getPostalCode())){ + target.getDelivery().setPostalCode( source.getPostalCode()); + } + + if(StringUtils.isNotBlank( source.getStateProvince())){ + target.getDelivery().setPostalCode( source.getStateProvince()); + } + } + + return target; + + } + + @Override + protected Customer createTarget() + { + return null; + } + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableCustomerDeliveryAddressPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableCustomerDeliveryAddressPopulator.java new file mode 100755 index 0000000000..16bb55abe1 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableCustomerDeliveryAddressPopulator.java @@ -0,0 +1,145 @@ +/** + * + */ +package com.salesmanager.shop.populator.customer; + +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.zone.ZoneService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.shop.model.customer.ReadableDelivery; + +/** + * @author Carl Samson + * + */ +public class ReadableCustomerDeliveryAddressPopulator extends AbstractDataPopulator +{ + + + private CountryService countryService; + private ZoneService zoneService; + + @Override + public ReadableDelivery populate( Delivery source, ReadableDelivery target, MerchantStore store, Language language ) + throws ConversionException + { + + + if(countryService==null) { + throw new ConversionException("countryService must be set"); + } + + if(zoneService==null) { + throw new ConversionException("zoneService must be set"); + } + + + target.setLatitude(source.getLatitude()); + target.setLongitude(source.getLongitude()); + + + if(StringUtils.isNotBlank( source.getCity() )){ + target.setCity(source.getCity()); + } + + if(StringUtils.isNotBlank( source.getCompany() )){ + target.setCompany(source.getCompany()); + } + + if(StringUtils.isNotBlank( source.getAddress() )){ + target.setAddress(source.getAddress()); + } + + if(StringUtils.isNotBlank( source.getFirstName() )){ + target.setFirstName(source.getFirstName()); + } + + if(StringUtils.isNotBlank( source.getLastName() )){ + target.setLastName(source.getLastName()); + } + + if(StringUtils.isNotBlank( source.getPostalCode() )){ + target.setPostalCode(source.getPostalCode()); + } + + if(StringUtils.isNotBlank( source.getTelephone() )){ + target.setPhone(source.getTelephone()); + } + + target.setStateProvince(source.getState()); + + if(source.getTelephone()==null) { + target.setPhone(source.getTelephone()); + } + target.setAddress(source.getAddress()); + if(source.getCountry()!=null) { + target.setCountry(source.getCountry().getIsoCode()); + + //resolve country name + try { + Map countries = countryService.getCountriesMap(language); + Country c =countries.get(source.getCountry().getIsoCode()); + if(c!=null) { + target.setCountryName(c.getName()); + } + } catch (ServiceException e) { + // TODO Auto-generated catch block + throw new ConversionException(e); + } + } + if(source.getZone()!=null) { + target.setZone(source.getZone().getCode()); + + //resolve zone name + try { + Map zones = zoneService.getZones(language); + Zone z = zones.get(source.getZone().getCode()); + if(z!=null) { + target.setProvinceName(z.getName()); + } + } catch (ServiceException e) { + // TODO Auto-generated catch block + throw new ConversionException(e); + } + } + + + + return target; + } + + @Override + protected ReadableDelivery createTarget() { + // TODO Auto-generated method stub + return null; + } + + public CountryService getCountryService() { + return countryService; + } + + public void setCountryService(CountryService countryService) { + this.countryService = countryService; + } + + public ZoneService getZoneService() { + return zoneService; + } + + public void setZoneService(ZoneService zoneService) { + this.zoneService = zoneService; + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableCustomerList.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableCustomerList.java new file mode 100755 index 0000000000..639d024bab --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableCustomerList.java @@ -0,0 +1,25 @@ +package com.salesmanager.shop.populator.customer; + +import java.util.ArrayList; +import java.util.List; +import com.salesmanager.shop.model.customer.ReadableCustomer; +import com.salesmanager.shop.model.entity.ReadableList; + +public class ReadableCustomerList extends ReadableList { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private List customers = new ArrayList(); + + public List getCustomers() { + return customers; + } + + public void setCustomers(List customers) { + this.customers = customers; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableCustomerOptionPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableCustomerOptionPopulator.java new file mode 100755 index 0000000000..f919e90c1d --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableCustomerOptionPopulator.java @@ -0,0 +1,81 @@ +package com.salesmanager.shop.populator.customer; + +import java.util.ArrayList; +import java.util.List; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.customer.attribute.CustomerOptionSet; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.customer.attribute.CustomerOption; +import com.salesmanager.shop.model.customer.attribute.CustomerOptionValue; + + + +public class ReadableCustomerOptionPopulator { + + /** +extends + AbstractDataPopulator { + + + private CustomerOptionSet optionSet; + + public CustomerOptionSet getOptionSet() { + return optionSet; + } + + public void setOptionSet(CustomerOptionSet optionSet) { + this.optionSet = optionSet; + } + + + @Override + public CustomerOption populate( + com.salesmanager.core.model.customer.attribute.CustomerOption source, + CustomerOption target, MerchantStore store, Language language) throws ConversionException { + + + CustomerOption customerOption = target; + if(customerOption==null) { + customerOption = new CustomerOption(); + } + + customerOption.setId(source.getId()); + customerOption.setType(source.getCustomerOptionType()); + customerOption.setName(source.getDescriptionsSettoList().get(0).getName()); + + List values = customerOption.getAvailableValues(); + if(values==null) { + values = new ArrayList(); + customerOption.setAvailableValues(values); + } + + com.salesmanager.core.model.customer.attribute.CustomerOptionValue optionValue = optionSet.getCustomerOptionValue(); + CustomerOptionValue custOptValue = new CustomerOptionValue(); + custOptValue.setId(optionValue.getId()); + custOptValue.setLanguage(language.getCode()); + custOptValue.setName(optionValue.getDescriptionsSettoList().get(0).getName()); + values.add(custOptValue); + + return customerOption; + + } + + @Override + protected CustomerOption createTarget() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public CustomerOption populate(com.salesmanager.core.model.customer.attribute.CustomerOption source, + CustomerOption target, MerchantStore store, Language language) throws ConversionException { + // TODO Auto-generated method stub + return null; + } + **/ + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableCustomerPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableCustomerPopulator.java new file mode 100755 index 0000000000..af30c1b6f2 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableCustomerPopulator.java @@ -0,0 +1,165 @@ +package com.salesmanager.shop.populator.customer; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.customer.attribute.CustomerAttribute; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.user.Group; +import com.salesmanager.shop.model.customer.ReadableCustomer; +import com.salesmanager.shop.model.customer.address.Address; +import com.salesmanager.shop.model.customer.attribute.CustomerOptionDescription; +import com.salesmanager.shop.model.customer.attribute.CustomerOptionValueDescription; +import com.salesmanager.shop.model.customer.attribute.ReadableCustomerAttribute; +import com.salesmanager.shop.model.customer.attribute.ReadableCustomerOption; +import com.salesmanager.shop.model.customer.attribute.ReadableCustomerOptionValue; +import com.salesmanager.shop.model.security.ReadableGroup; +import org.apache.commons.lang3.StringUtils; + +public class ReadableCustomerPopulator extends + AbstractDataPopulator { + + + + @Override + public ReadableCustomer populate(Customer source, ReadableCustomer target, + MerchantStore store, Language language) throws ConversionException { + + try { + + if(target == null) { + target = new ReadableCustomer(); + } + + if(source.getId()!=null && source.getId()>0) { + target.setId(source.getId()); + } + target.setEmailAddress(source.getEmailAddress()); + + if (StringUtils.isNotEmpty(source.getNick())) { + target.setUserName(source.getNick()); + } + + if (source.getDefaultLanguage()!= null) { + target.setLanguage(source.getDefaultLanguage().getCode()); + } + + if (source.getGender()!= null) { + target.setGender(source.getGender().name()); + } + + if (StringUtils.isNotEmpty(source.getProvider())) { + target.setProvider(source.getProvider()); + } + + if(source.getBilling()!=null) { + Address address = new Address(); + address.setAddress(source.getBilling().getAddress()); + address.setCity(source.getBilling().getCity()); + address.setCompany(source.getBilling().getCompany()); + address.setFirstName(source.getBilling().getFirstName()); + address.setLastName(source.getBilling().getLastName()); + address.setPostalCode(source.getBilling().getPostalCode()); + address.setPhone(source.getBilling().getTelephone()); + if(source.getBilling().getCountry()!=null) { + address.setCountry(source.getBilling().getCountry().getIsoCode()); + } + if(source.getBilling().getZone()!=null) { + address.setZone(source.getBilling().getZone().getCode()); + } + if(source.getBilling().getState()!=null) { + address.setStateProvince(source.getBilling().getState()); + } + + target.setFirstName(address.getFirstName()); + target.setLastName(address.getLastName()); + + target.setBilling(address); + } + + if(source.getCustomerReviewAvg() != null) { + target.setRating(source.getCustomerReviewAvg().doubleValue()); + } + + if(source.getCustomerReviewCount() != null) { + target.setRatingCount(source.getCustomerReviewCount().intValue()); + } + + if(source.getDelivery()!=null) { + Address address = new Address(); + address.setCity(source.getDelivery().getCity()); + address.setAddress(source.getDelivery().getAddress()); + address.setCompany(source.getDelivery().getCompany()); + address.setFirstName(source.getDelivery().getFirstName()); + address.setLastName(source.getDelivery().getLastName()); + address.setPostalCode(source.getDelivery().getPostalCode()); + address.setPhone(source.getDelivery().getTelephone()); + if(source.getDelivery().getCountry()!=null) { + address.setCountry(source.getDelivery().getCountry().getIsoCode()); + } + if(source.getDelivery().getZone()!=null) { + address.setZone(source.getDelivery().getZone().getCode()); + } + if(source.getDelivery().getState()!=null) { + address.setStateProvince(source.getDelivery().getState()); + } + + target.setDelivery(address); + } + + if(source.getAttributes()!=null) { + for(CustomerAttribute attribute : source.getAttributes()) { + ReadableCustomerAttribute readableAttribute = new ReadableCustomerAttribute(); + readableAttribute.setId(attribute.getId()); + readableAttribute.setTextValue(attribute.getTextValue()); + ReadableCustomerOption option = new ReadableCustomerOption(); + option.setId(attribute.getCustomerOption().getId()); + option.setCode(attribute.getCustomerOption().getCode()); + + CustomerOptionDescription d = new CustomerOptionDescription(); + d.setDescription(attribute.getCustomerOption().getDescriptionsSettoList().get(0).getDescription()); + d.setName(attribute.getCustomerOption().getDescriptionsSettoList().get(0).getName()); + option.setDescription(d); + + readableAttribute.setCustomerOption(option); + + ReadableCustomerOptionValue optionValue = new ReadableCustomerOptionValue(); + optionValue.setId(attribute.getCustomerOptionValue().getId()); + CustomerOptionValueDescription vd = new CustomerOptionValueDescription(); + vd.setDescription(attribute.getCustomerOptionValue().getDescriptionsSettoList().get(0).getDescription()); + vd.setName(attribute.getCustomerOptionValue().getDescriptionsSettoList().get(0).getName()); + optionValue.setCode(attribute.getCustomerOptionValue().getCode()); + optionValue.setDescription(vd); + + + readableAttribute.setCustomerOptionValue(optionValue); + target.getAttributes().add(readableAttribute); + } + + if(source.getGroups() != null) { + for(Group group : source.getGroups()) { + ReadableGroup readableGroup = new ReadableGroup(); + readableGroup.setId(group.getId().longValue()); + readableGroup.setName(group.getGroupName()); + readableGroup.setType(group.getGroupType().name()); + target.getGroups().add( + readableGroup + ); + } + } + } + + } catch (Exception e) { + throw new ConversionException(e); + } + + return target; + } + + @Override + protected ReadableCustomer createTarget() { + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableCustomerReviewPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableCustomerReviewPopulator.java new file mode 100755 index 0000000000..318b4ce48f --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableCustomerReviewPopulator.java @@ -0,0 +1,86 @@ +package com.salesmanager.shop.populator.customer; + +import java.util.Set; + +import org.apache.commons.collections4.CollectionUtils; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.customer.review.CustomerReview; +import com.salesmanager.core.model.customer.review.CustomerReviewDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.customer.ReadableCustomer; +import com.salesmanager.shop.model.customer.ReadableCustomerReview; +import com.salesmanager.shop.utils.DateUtil; + +public class ReadableCustomerReviewPopulator extends AbstractDataPopulator { + + @Override + public ReadableCustomerReview populate(CustomerReview source, ReadableCustomerReview target, MerchantStore store, + Language language) throws ConversionException { + + try { + + if(target==null) { + target = new ReadableCustomerReview(); + } + + if(source.getReviewDate() != null) { + target.setDate(DateUtil.formatDate(source.getReviewDate())); + } + + + ReadableCustomer reviewed = new ReadableCustomer(); + reviewed.setId(source.getReviewedCustomer().getId()); + reviewed.setFirstName(source.getReviewedCustomer().getBilling().getFirstName()); + reviewed.setLastName(source.getReviewedCustomer().getBilling().getLastName()); + + + target.setId(source.getId()); + target.setCustomerId(source.getCustomer().getId()); + target.setReviewedCustomer(reviewed); + target.setRating(source.getReviewRating()); + target.setReviewedCustomer(reviewed); + target.setCustomerId(source.getCustomer().getId()); + + Set descriptions = source.getDescriptions(); + if(CollectionUtils.isNotEmpty(descriptions)) { + CustomerReviewDescription description = null; + if(descriptions.size()>1) { + for(CustomerReviewDescription desc : descriptions) { + if(desc.getLanguage().getCode().equals(language.getCode())) { + description = desc; + break; + } + } + } else { + description = descriptions.iterator().next(); + } + + if(description != null) { + target.setDescription(description.getDescription()); + target.setLanguage(description.getLanguage().getCode()); + } + + } + + + + + } catch (Exception e) { + throw new ConversionException("Cannot populate ReadableCustomerReview", e); + } + + + return target; + + } + + @Override + protected ReadableCustomerReview createTarget() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableProductReviewPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableProductReviewPopulator.java new file mode 100755 index 0000000000..c7136fc3f0 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/customer/ReadableProductReviewPopulator.java @@ -0,0 +1,25 @@ +package com.salesmanager.shop.populator.customer; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.customer.review.CustomerReview; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.customer.ReadableCustomerReview; + +public class ReadableProductReviewPopulator extends AbstractDataPopulator { + + @Override + public ReadableCustomerReview populate(CustomerReview source, ReadableCustomerReview target, MerchantStore store, + Language language) throws ConversionException { + // TODO Auto-generated method stub + return null; + } + + @Override + protected ReadableCustomerReview createTarget() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/manufacturer/PersistableManufacturerPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/manufacturer/PersistableManufacturerPopulator.java new file mode 100755 index 0000000000..dbede0043b --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/manufacturer/PersistableManufacturerPopulator.java @@ -0,0 +1,96 @@ + +package com.salesmanager.shop.populator.manufacturer; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.manufacturer.ManufacturerDescription; +import com.salesmanager.shop.model.catalog.manufacturer.PersistableManufacturer; + + +/** + * @author Carl Samson + * + */ + + +public class PersistableManufacturerPopulator extends AbstractDataPopulator +{ + + + private LanguageService languageService; + + @Override + public Manufacturer populate(PersistableManufacturer source, + Manufacturer target, MerchantStore store, Language language) + throws ConversionException { + + Validate.notNull(languageService, "Requires to set LanguageService"); + + try { + + target.setMerchantStore(store); + target.setCode(source.getCode()); + + + if(!CollectionUtils.isEmpty(source.getDescriptions())) { + Set descriptions = new HashSet(); + for(ManufacturerDescription description : source.getDescriptions()) { + com.salesmanager.core.model.catalog.product.manufacturer.ManufacturerDescription desc = new com.salesmanager.core.model.catalog.product.manufacturer.ManufacturerDescription(); + if(desc.getId() != null && desc.getId().longValue()>0) { + desc.setId(description.getId()); + } + if(target.getDescriptions() != null) { + for(com.salesmanager.core.model.catalog.product.manufacturer.ManufacturerDescription d : target.getDescriptions()) { + if(d.getLanguage().getCode().equals(description.getLanguage()) || desc.getId() != null && d.getId().longValue() == desc.getId().longValue()) { + desc = d; + } + } + } + + desc.setManufacturer(target); + desc.setDescription(description.getDescription()); + desc.setName(description.getName()); + Language lang = languageService.getByCode(description.getLanguage()); + if(lang==null) { + throw new ConversionException("Language is null for code " + description.getLanguage() + " use language ISO code [en, fr ...]"); + } + desc.setLanguage(lang); + descriptions.add(desc); + } + target.setDescriptions(descriptions); + } + + } catch (Exception e) { + throw new ConversionException(e); + } + + + return target; + } + + @Override + protected Manufacturer createTarget() { + // TODO Auto-generated method stub + return null; + } + + public void setLanguageService(LanguageService languageService) { + this.languageService = languageService; + } + + public LanguageService getLanguageService() { + return languageService; + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/manufacturer/ReadableManufacturerPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/manufacturer/ReadableManufacturerPopulator.java new file mode 100755 index 0000000000..8f87448644 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/manufacturer/ReadableManufacturerPopulator.java @@ -0,0 +1,89 @@ +package com.salesmanager.shop.populator.manufacturer; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.catalog.product.manufacturer.ManufacturerDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.manufacturer.ReadableManufacturer; +import com.salesmanager.shop.model.catalog.manufacturer.ReadableManufacturerFull; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +public class ReadableManufacturerPopulator extends + AbstractDataPopulator { + + + + @Override + public ReadableManufacturer populate( + com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer source, + ReadableManufacturer target, MerchantStore store, Language language) + throws ConversionException { + + + if (language == null) { + target = new ReadableManufacturerFull(); + } + target.setOrder(source.getOrder()); + target.setId(source.getId()); + target.setCode(source.getCode()); + if (source.getDescriptions() != null && source.getDescriptions().size() > 0) { + + List fulldescriptions = + new ArrayList(); + + Set descriptions = source.getDescriptions(); + ManufacturerDescription description = null; + for (ManufacturerDescription desc : descriptions) { + if (language != null && desc.getLanguage().getCode().equals(language.getCode())) { + description = desc; + break; + } else { + fulldescriptions.add(populateDescription(desc)); + } + } + + + + if (description != null) { + com.salesmanager.shop.model.catalog.manufacturer.ManufacturerDescription d = + populateDescription(description); + target.setDescription(d); + } + + if (target instanceof ReadableManufacturerFull) { + ((ReadableManufacturerFull) target).setDescriptions(fulldescriptions); + } + + } + + + + return target; + } + + @Override + protected ReadableManufacturer createTarget() { + return null; + } + + com.salesmanager.shop.model.catalog.manufacturer.ManufacturerDescription populateDescription( + ManufacturerDescription description) { + if (description == null) { + return null; + } + com.salesmanager.shop.model.catalog.manufacturer.ManufacturerDescription d = + new com.salesmanager.shop.model.catalog.manufacturer.ManufacturerDescription(); + d.setName(description.getName()); + d.setDescription(description.getDescription()); + d.setId(description.getId()); + d.setTitle(description.getTitle()); + if (description.getLanguage() != null) { + d.setLanguage(description.getLanguage().getCode()); + } + return d; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/order/OrderProductPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/OrderProductPopulator.java new file mode 100755 index 0000000000..8965b62a7b --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/OrderProductPopulator.java @@ -0,0 +1,191 @@ +package com.salesmanager.shop.populator.order; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService; +import com.salesmanager.core.business.services.catalog.product.file.DigitalProductService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.file.DigitalProduct; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.orderproduct.OrderProduct; +import com.salesmanager.core.model.order.orderproduct.OrderProductAttribute; +import com.salesmanager.core.model.order.orderproduct.OrderProductDownload; +import com.salesmanager.core.model.order.orderproduct.OrderProductPrice; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shoppingcart.ShoppingCartAttributeItem; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.shop.constants.ApplicationConstants; + +public class OrderProductPopulator extends + AbstractDataPopulator { + + private ProductService productService; + private DigitalProductService digitalProductService; + private ProductAttributeService productAttributeService; + + + public ProductAttributeService getProductAttributeService() { + return productAttributeService; + } + + public void setProductAttributeService( + ProductAttributeService productAttributeService) { + this.productAttributeService = productAttributeService; + } + + public DigitalProductService getDigitalProductService() { + return digitalProductService; + } + + public void setDigitalProductService(DigitalProductService digitalProductService) { + this.digitalProductService = digitalProductService; + } + + /** + * Converts a ShoppingCartItem carried in the ShoppingCart to an OrderProduct + * that will be saved in the system + */ + @Override + public OrderProduct populate(ShoppingCartItem source, OrderProduct target, + MerchantStore store, Language language) throws ConversionException { + + Validate.notNull(productService,"productService must be set"); + Validate.notNull(digitalProductService,"digitalProductService must be set"); + Validate.notNull(productAttributeService,"productAttributeService must be set"); + + + try { + Product modelProduct = productService.getBySku(source.getSku(), store, language); + if(modelProduct==null) { + throw new ConversionException("Cannot get product with sku " + source.getSku()); + } + + if(modelProduct.getMerchantStore().getId().intValue()!=store.getId().intValue()) { + throw new ConversionException("Invalid product with sku " + source.getSku()); + } + + DigitalProduct digitalProduct = digitalProductService.getByProduct(store, modelProduct); + + if(digitalProduct!=null) { + OrderProductDownload orderProductDownload = new OrderProductDownload(); + orderProductDownload.setOrderProductFilename(digitalProduct.getProductFileName()); + orderProductDownload.setOrderProduct(target); + orderProductDownload.setDownloadCount(0); + orderProductDownload.setMaxdays(ApplicationConstants.MAX_DOWNLOAD_DAYS); + target.getDownloads().add(orderProductDownload); + } + + target.setOneTimeCharge(source.getItemPrice()); + target.setProductName(source.getProduct().getDescriptions().iterator().next().getName()); + target.setProductQuantity(source.getQuantity()); + target.setSku(source.getProduct().getSku()); + + FinalPrice finalPrice = source.getFinalPrice(); + if(finalPrice==null) { + throw new ConversionException("Object final price not populated in shoppingCartItem (source)"); + } + //Default price + OrderProductPrice orderProductPrice = orderProductPrice(finalPrice); + orderProductPrice.setOrderProduct(target); + + Set prices = new HashSet(); + prices.add(orderProductPrice); + + //Other prices + List otherPrices = finalPrice.getAdditionalPrices(); + if(otherPrices!=null) { + for(FinalPrice otherPrice : otherPrices) { + OrderProductPrice other = orderProductPrice(otherPrice); + other.setOrderProduct(target); + prices.add(other); + } + } + + target.setPrices(prices); + + //OrderProductAttribute + Set attributeItems = source.getAttributes(); + if(!CollectionUtils.isEmpty(attributeItems)) { + Set attributes = new HashSet(); + for(ShoppingCartAttributeItem attribute : attributeItems) { + OrderProductAttribute orderProductAttribute = new OrderProductAttribute(); + orderProductAttribute.setOrderProduct(target); + Long id = attribute.getProductAttributeId(); + ProductAttribute attr = productAttributeService.getById(id); + if(attr==null) { + throw new ConversionException("Attribute id " + id + " does not exists"); + } + + if(attr.getProduct().getMerchantStore().getId().intValue()!=store.getId().intValue()) { + throw new ConversionException("Attribute id " + id + " invalid for this store"); + } + + orderProductAttribute.setProductAttributeIsFree(attr.getProductAttributeIsFree()); + orderProductAttribute.setProductAttributeName(attr.getProductOption().getDescriptionsSettoList().get(0).getName()); + orderProductAttribute.setProductAttributeValueName(attr.getProductOptionValue().getDescriptionsSettoList().get(0).getName()); + orderProductAttribute.setProductAttributePrice(attr.getProductAttributePrice()); + orderProductAttribute.setProductAttributeWeight(attr.getProductAttributeWeight()); + orderProductAttribute.setProductOptionId(attr.getProductOption().getId()); + orderProductAttribute.setProductOptionValueId(attr.getProductOptionValue().getId()); + attributes.add(orderProductAttribute); + } + target.setOrderAttributes(attributes); + } + + + } catch (Exception e) { + throw new ConversionException(e); + } + + + return target; + } + + @Override + protected OrderProduct createTarget() { + return null; + } + + public void setProductService(ProductService productService) { + this.productService = productService; + } + + public ProductService getProductService() { + return productService; + } + + private OrderProductPrice orderProductPrice(FinalPrice price) { + + OrderProductPrice orderProductPrice = new OrderProductPrice(); + + ProductPrice productPrice = price.getProductPrice(); + + orderProductPrice.setDefaultPrice(productPrice.isDefaultPrice()); + + orderProductPrice.setProductPrice(price.getFinalPrice()); + orderProductPrice.setProductPriceCode(productPrice.getCode()); + if(productPrice.getDescriptions()!=null && productPrice.getDescriptions().size()>0) { + orderProductPrice.setProductPriceName(productPrice.getDescriptions().iterator().next().getName()); + } + if(price.isDiscounted()) { + orderProductPrice.setProductPriceSpecial(productPrice.getProductPriceSpecialAmount()); + orderProductPrice.setProductPriceSpecialStartDate(productPrice.getProductPriceSpecialStartDate()); + orderProductPrice.setProductPriceSpecialEndDate(productPrice.getProductPriceSpecialEndDate()); + } + + return orderProductPrice; + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/order/PersistableOrderApiPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/PersistableOrderApiPopulator.java new file mode 100755 index 0000000000..f80c0e6ebd --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/PersistableOrderApiPopulator.java @@ -0,0 +1,221 @@ +package com.salesmanager.shop.populator.order; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.reference.currency.CurrencyService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.common.Billing; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.order.OrderChannel; +import com.salesmanager.core.model.order.attributes.OrderAttribute; +import com.salesmanager.core.model.order.orderstatus.OrderStatus; +import com.salesmanager.core.model.order.orderstatus.OrderStatusHistory; +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.core.model.reference.currency.Currency; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.customer.PersistableCustomer; +import com.salesmanager.shop.model.order.v1.PersistableAnonymousOrder; +import com.salesmanager.shop.model.order.v1.PersistableOrder; +import com.salesmanager.shop.populator.customer.CustomerPopulator; +import com.salesmanager.shop.utils.LocaleUtils; + +@Component +public class PersistableOrderApiPopulator extends AbstractDataPopulator { + + @Autowired + private CurrencyService currencyService; + @Autowired + private CustomerService customerService; +/* @Autowired + private ShoppingCartService shoppingCartService; + @Autowired + private ProductService productService; + @Autowired + private ProductAttributeService productAttributeService; + @Autowired + private DigitalProductService digitalProductService;*/ + @Autowired + private CustomerPopulator customerPopulator; + + + + + + + @Override + public Order populate(PersistableOrder source, Order target, MerchantStore store, Language language) + throws ConversionException { + + +/* Validate.notNull(currencyService,"currencyService must be set"); + Validate.notNull(customerService,"customerService must be set"); + Validate.notNull(shoppingCartService,"shoppingCartService must be set"); + Validate.notNull(productService,"productService must be set"); + Validate.notNull(productAttributeService,"productAttributeService must be set"); + Validate.notNull(digitalProductService,"digitalProductService must be set");*/ + Validate.notNull(source.getPayment(),"Payment cannot be null"); + + try { + + if(target == null) { + target = new Order(); + } + + //target.setLocale(LocaleUtils.getLocale(store)); + + target.setLocale(LocaleUtils.getLocale(store)); + + + Currency currency = null; + try { + currency = currencyService.getByCode(source.getCurrency()); + } catch(Exception e) { + throw new ConversionException("Currency not found for code " + source.getCurrency()); + } + + if(currency==null) { + throw new ConversionException("Currency not found for code " + source.getCurrency()); + } + + //Customer + Customer customer = null; + if(source.getCustomerId() != null && source.getCustomerId().longValue() >0) { + Long customerId = source.getCustomerId(); + customer = customerService.getById(customerId); + + if(customer == null) { + throw new ConversionException("Curstomer with id " + source.getCustomerId() + " does not exist"); + } + target.setCustomerId(customerId); + + } else { + if(source instanceof PersistableAnonymousOrder) { + PersistableCustomer persistableCustomer = ((PersistableAnonymousOrder)source).getCustomer(); + customer = new Customer(); + customer = customerPopulator.populate(persistableCustomer, customer, store, language); + } else { + throw new ConversionException("Curstomer details or id not set in request"); + } + } + + + target.setCustomerEmailAddress(customer.getEmailAddress()); + + Delivery delivery = customer.getDelivery(); + target.setDelivery(delivery); + + Billing billing = customer.getBilling(); + target.setBilling(billing); + + if(source.getAttributes() != null && source.getAttributes().size() > 0) { + Set attrs = new HashSet(); + for(com.salesmanager.shop.model.order.OrderAttribute attribute : source.getAttributes()) { + OrderAttribute attr = new OrderAttribute(); + attr.setKey(attribute.getKey()); + attr.setValue(attribute.getValue()); + attr.setOrder(target); + attrs.add(attr); + } + target.setOrderAttributes(attrs); + } + + target.setDatePurchased(new Date()); + target.setCurrency(currency); + target.setCurrencyValue(new BigDecimal(0)); + target.setMerchant(store); + target.setChannel(OrderChannel.API); + //need this + target.setStatus(OrderStatus.ORDERED); + target.setPaymentModuleCode(source.getPayment().getPaymentModule()); + target.setPaymentType(PaymentType.valueOf(source.getPayment().getPaymentType())); + + target.setCustomerAgreement(source.isCustomerAgreement()); + target.setConfirmedAddress(true);//force this to true, cannot perform this activity from the API + + + if(!StringUtils.isBlank(source.getComments())) { + OrderStatusHistory statusHistory = new OrderStatusHistory(); + statusHistory.setStatus(null); + statusHistory.setOrder(target); + statusHistory.setComments(source.getComments()); + target.getOrderHistory().add(statusHistory); + } + + return target; + + } catch(Exception e) { + throw new ConversionException(e); + } + } + + @Override + protected Order createTarget() { + // TODO Auto-generated method stub + return null; + } + + +/* public CurrencyService getCurrencyService() { + return currencyService; + } + + public void setCurrencyService(CurrencyService currencyService) { + this.currencyService = currencyService; + } + + public CustomerService getCustomerService() { + return customerService; + } + + public void setCustomerService(CustomerService customerService) { + this.customerService = customerService; + } + + public ShoppingCartService getShoppingCartService() { + return shoppingCartService; + } + + public void setShoppingCartService(ShoppingCartService shoppingCartService) { + this.shoppingCartService = shoppingCartService; + } + + public ProductService getProductService() { + return productService; + } + + public void setProductService(ProductService productService) { + this.productService = productService; + } + + public ProductAttributeService getProductAttributeService() { + return productAttributeService; + } + + public void setProductAttributeService(ProductAttributeService productAttributeService) { + this.productAttributeService = productAttributeService; + } + + public DigitalProductService getDigitalProductService() { + return digitalProductService; + } + + public void setDigitalProductService(DigitalProductService digitalProductService) { + this.digitalProductService = digitalProductService; + }*/ + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/order/PersistableOrderPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/PersistableOrderPopulator.java new file mode 100755 index 0000000000..247be06eaa --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/PersistableOrderPopulator.java @@ -0,0 +1,236 @@ +package com.salesmanager.shop.populator.order; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService; +import com.salesmanager.core.business.services.catalog.product.file.DigitalProductService; +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.currency.CurrencyService; +import com.salesmanager.core.business.services.reference.zone.ZoneService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.business.utils.CreditCardUtils; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.order.orderproduct.OrderProduct; +import com.salesmanager.core.model.order.orderstatus.OrderStatus; +import com.salesmanager.core.model.order.orderstatus.OrderStatusHistory; +import com.salesmanager.core.model.order.payment.CreditCard; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.currency.Currency; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.shop.model.customer.PersistableCustomer; +import com.salesmanager.shop.model.order.PersistableOrderProduct; +import com.salesmanager.shop.model.order.total.OrderTotal; +import com.salesmanager.shop.model.order.v0.PersistableOrder; +import com.salesmanager.shop.utils.LocaleUtils; + +public class PersistableOrderPopulator extends + AbstractDataPopulator { + + private CustomerService customerService; + private CountryService countryService; + private CurrencyService currencyService; + + + private ZoneService zoneService; + private ProductService productService; + private DigitalProductService digitalProductService; + private ProductAttributeService productAttributeService; + + @Override + public Order populate(PersistableOrder source, Order target, + MerchantStore store, Language language) throws ConversionException { + + + Validate.notNull(productService,"productService must be set"); + Validate.notNull(digitalProductService,"digitalProductService must be set"); + Validate.notNull(productAttributeService,"productAttributeService must be set"); + Validate.notNull(customerService,"customerService must be set"); + Validate.notNull(countryService,"countryService must be set"); + Validate.notNull(zoneService,"zoneService must be set"); + Validate.notNull(currencyService,"currencyService must be set"); + + try { + + + Map countriesMap = countryService.getCountriesMap(language); + Map zonesMap = zoneService.getZones(language); + /** customer **/ + PersistableCustomer customer = source.getCustomer(); + if(customer!=null) { + if(customer.getId()!=null && customer.getId()>0) { + Customer modelCustomer = customerService.getById(customer.getId()); + if(modelCustomer==null) { + throw new ConversionException("Customer id " + customer.getId() + " does not exists"); + } + if(modelCustomer.getMerchantStore().getId().intValue()!=store.getId().intValue()) { + throw new ConversionException("Customer id " + customer.getId() + " does not exists for store " + store.getCode()); + } + target.setCustomerId(modelCustomer.getId()); + target.setBilling(modelCustomer.getBilling()); + target.setDelivery(modelCustomer.getDelivery()); + target.setCustomerEmailAddress(source.getCustomer().getEmailAddress()); + + + + } + } + + target.setLocale(LocaleUtils.getLocale(store)); + + CreditCard creditCard = source.getCreditCard(); + if(creditCard!=null) { + String maskedNumber = CreditCardUtils.maskCardNumber(creditCard.getCcNumber()); + creditCard.setCcNumber(maskedNumber); + target.setCreditCard(creditCard); + } + + Currency currency = null; + try { + currency = currencyService.getByCode(source.getCurrency()); + } catch(Exception e) { + throw new ConversionException("Currency not found for code " + source.getCurrency()); + } + + if(currency==null) { + throw new ConversionException("Currency not found for code " + source.getCurrency()); + } + + target.setCurrency(currency); + target.setDatePurchased(source.getDatePurchased()); + //target.setCurrency(store.getCurrency()); + target.setCurrencyValue(new BigDecimal(0)); + target.setMerchant(store); + target.setStatus(source.getOrderStatus()); + target.setPaymentModuleCode(source.getPaymentModule()); + target.setPaymentType(source.getPaymentType()); + target.setShippingModuleCode(source.getShippingModule()); + target.setCustomerAgreement(source.isCustomerAgreed()); + target.setConfirmedAddress(source.isConfirmedAddress()); + if(source.getPreviousOrderStatus()!=null) { + List orderStatusList = source.getPreviousOrderStatus(); + for(OrderStatus status : orderStatusList) { + OrderStatusHistory statusHistory = new OrderStatusHistory(); + statusHistory.setStatus(status); + statusHistory.setOrder(target); + target.getOrderHistory().add(statusHistory); + } + } + + if(!StringUtils.isBlank(source.getComments())) { + OrderStatusHistory statusHistory = new OrderStatusHistory(); + statusHistory.setStatus(null); + statusHistory.setOrder(target); + statusHistory.setComments(source.getComments()); + target.getOrderHistory().add(statusHistory); + } + + List products = source.getOrderProductItems(); + if(CollectionUtils.isEmpty(products)) { + throw new ConversionException("Requires at least 1 PersistableOrderProduct"); + } + com.salesmanager.shop.populator.order.PersistableOrderProductPopulator orderProductPopulator = new PersistableOrderProductPopulator(); + orderProductPopulator.setProductAttributeService(productAttributeService); + orderProductPopulator.setProductService(productService); + orderProductPopulator.setDigitalProductService(digitalProductService); + + for(PersistableOrderProduct orderProduct : products) { + OrderProduct modelOrderProduct = new OrderProduct(); + orderProductPopulator.populate(orderProduct, modelOrderProduct, store, language); + target.getOrderProducts().add(modelOrderProduct); + } + + List orderTotals = source.getTotals(); + if(CollectionUtils.isNotEmpty(orderTotals)) { + for(OrderTotal total : orderTotals) { + com.salesmanager.core.model.order.OrderTotal totalModel = new com.salesmanager.core.model.order.OrderTotal(); + totalModel.setModule(total.getModule()); + totalModel.setOrder(target); + totalModel.setOrderTotalCode(total.getCode()); + totalModel.setTitle(total.getTitle()); + totalModel.setValue(total.getValue()); + target.getOrderTotal().add(totalModel); + } + } + + } catch (Exception e) { + throw new ConversionException(e); + } + + + return target; + } + + @Override + protected Order createTarget() { + return null; + } + + public void setProductService(ProductService productService) { + this.productService = productService; + } + + public ProductService getProductService() { + return productService; + } + + public void setDigitalProductService(DigitalProductService digitalProductService) { + this.digitalProductService = digitalProductService; + } + + public DigitalProductService getDigitalProductService() { + return digitalProductService; + } + + public void setProductAttributeService(ProductAttributeService productAttributeService) { + this.productAttributeService = productAttributeService; + } + + public ProductAttributeService getProductAttributeService() { + return productAttributeService; + } + + public CustomerService getCustomerService() { + return customerService; + } + + public void setCustomerService(CustomerService customerService) { + this.customerService = customerService; + } + + public CountryService getCountryService() { + return countryService; + } + + public void setCountryService(CountryService countryService) { + this.countryService = countryService; + } + + public CurrencyService getCurrencyService() { + return currencyService; + } + + public void setCurrencyService(CurrencyService currencyService) { + this.currencyService = currencyService; + } + + public ZoneService getZoneService() { + return zoneService; + } + + public void setZoneService(ZoneService zoneService) { + this.zoneService = zoneService; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/order/PersistableOrderProductPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/PersistableOrderProductPopulator.java new file mode 100755 index 0000000000..4518cb2efd --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/PersistableOrderProductPopulator.java @@ -0,0 +1,167 @@ +package com.salesmanager.shop.populator.order; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService; +import com.salesmanager.core.business.services.catalog.product.file.DigitalProductService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.file.DigitalProduct; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.orderproduct.OrderProduct; +import com.salesmanager.core.model.order.orderproduct.OrderProductAttribute; +import com.salesmanager.core.model.order.orderproduct.OrderProductDownload; +import com.salesmanager.core.model.order.orderproduct.OrderProductPrice; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.constants.ApplicationConstants; +import com.salesmanager.shop.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.shop.model.order.PersistableOrderProduct; + +public class PersistableOrderProductPopulator extends + AbstractDataPopulator { + + private ProductService productService; + private DigitalProductService digitalProductService; + private ProductAttributeService productAttributeService; + + + public ProductAttributeService getProductAttributeService() { + return productAttributeService; + } + + public void setProductAttributeService( + ProductAttributeService productAttributeService) { + this.productAttributeService = productAttributeService; + } + + public DigitalProductService getDigitalProductService() { + return digitalProductService; + } + + public void setDigitalProductService(DigitalProductService digitalProductService) { + this.digitalProductService = digitalProductService; + } + + /** + * Converts a ShoppingCartItem carried in the ShoppingCart to an OrderProduct + * that will be saved in the system + */ + @Override + public OrderProduct populate(PersistableOrderProduct source, OrderProduct target, + MerchantStore store, Language language) throws ConversionException { + + Validate.notNull(productService,"productService must be set"); + Validate.notNull(digitalProductService,"digitalProductService must be set"); + Validate.notNull(productAttributeService,"productAttributeService must be set"); + + + try { + Product modelProduct = productService.getById(source.getProduct().getId()); + if(modelProduct==null) { + throw new ConversionException("Cannot get product with id (productId) " + source.getProduct().getId()); + } + + if(modelProduct.getMerchantStore().getId().intValue()!=store.getId().intValue()) { + throw new ConversionException("Invalid product id " + source.getProduct().getId()); + } + + DigitalProduct digitalProduct = digitalProductService.getByProduct(store, modelProduct); + + if(digitalProduct!=null) { + OrderProductDownload orderProductDownload = new OrderProductDownload(); + orderProductDownload.setOrderProductFilename(digitalProduct.getProductFileName()); + orderProductDownload.setOrderProduct(target); + orderProductDownload.setDownloadCount(0); + orderProductDownload.setMaxdays(ApplicationConstants.MAX_DOWNLOAD_DAYS); + target.getDownloads().add(orderProductDownload); + } + + target.setOneTimeCharge(source.getPrice()); + target.setProductName(source.getProduct().getDescription().getName()); + target.setProductQuantity(source.getOrderedQuantity()); + target.setSku(source.getProduct().getSku()); + + OrderProductPrice orderProductPrice = new OrderProductPrice(); + orderProductPrice.setDefaultPrice(true); + orderProductPrice.setProductPrice(source.getPrice()); + orderProductPrice.setOrderProduct(target); + + + + Set prices = new HashSet(); + prices.add(orderProductPrice); + + /** DO NOT SUPPORT MUTIPLE PRICES **/ +/* //Other prices + List otherPrices = finalPrice.getAdditionalPrices(); + if(otherPrices!=null) { + for(FinalPrice otherPrice : otherPrices) { + OrderProductPrice other = orderProductPrice(otherPrice); + other.setOrderProduct(target); + prices.add(other); + } + }*/ + + target.setPrices(prices); + + //OrderProductAttribute + List attributeItems = source.getAttributes(); + if(!CollectionUtils.isEmpty(attributeItems)) { + Set attributes = new HashSet(); + for(ProductAttribute attribute : attributeItems) { + OrderProductAttribute orderProductAttribute = new OrderProductAttribute(); + orderProductAttribute.setOrderProduct(target); + Long id = attribute.getId(); + com.salesmanager.core.model.catalog.product.attribute.ProductAttribute attr = productAttributeService.getById(id); + if(attr==null) { + throw new ConversionException("Attribute id " + id + " does not exists"); + } + + if(attr.getProduct().getMerchantStore().getId().intValue()!=store.getId().intValue()) { + throw new ConversionException("Attribute id " + id + " invalid for this store"); + } + + orderProductAttribute.setProductAttributeIsFree(attr.getProductAttributeIsFree()); + orderProductAttribute.setProductAttributeName(attr.getProductOption().getDescriptionsSettoList().get(0).getName()); + orderProductAttribute.setProductAttributeValueName(attr.getProductOptionValue().getDescriptionsSettoList().get(0).getName()); + orderProductAttribute.setProductAttributePrice(attr.getProductAttributePrice()); + orderProductAttribute.setProductAttributeWeight(attr.getProductAttributeWeight()); + orderProductAttribute.setProductOptionId(attr.getProductOption().getId()); + orderProductAttribute.setProductOptionValueId(attr.getProductOptionValue().getId()); + attributes.add(orderProductAttribute); + } + target.setOrderAttributes(attributes); + } + + + } catch (Exception e) { + throw new ConversionException(e); + } + + + return target; + } + + @Override + protected OrderProduct createTarget() { + return null; + } + + public void setProductService(ProductService productService) { + this.productService = productService; + } + + public ProductService getProductService() { + return productService; + } + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableOrderPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableOrderPopulator.java new file mode 100755 index 0000000000..3815ffcbbe --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableOrderPopulator.java @@ -0,0 +1,213 @@ +package com.salesmanager.shop.populator.order; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + + + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.zone.ZoneService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.order.OrderTotal; +import com.salesmanager.core.model.order.OrderTotalType; +import com.salesmanager.core.model.order.attributes.OrderAttribute; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.customer.ReadableBilling; +import com.salesmanager.shop.model.customer.ReadableDelivery; +import com.salesmanager.shop.model.customer.address.Address; +import com.salesmanager.shop.model.order.v0.ReadableOrder; +import com.salesmanager.shop.model.store.ReadableMerchantStore; + +import org.springframework.beans.factory.annotation.Qualifier; +import com.salesmanager.shop.populator.store.ReadableMerchantStorePopulator; +import com.salesmanager.shop.utils.ImageFilePath; + +@Component +public class ReadableOrderPopulator extends + AbstractDataPopulator { + + @Autowired + private CountryService countryService; + @Autowired + private ZoneService zoneService; + + @Autowired + @Qualifier("img") + private ImageFilePath filePath; + + @Autowired + private ReadableMerchantStorePopulator readableMerchantStorePopulator; + + + @Override + public ReadableOrder populate(Order source, ReadableOrder target, + MerchantStore store, Language language) throws ConversionException { + + + + target.setId(source.getId()); + target.setDatePurchased(source.getDatePurchased()); + target.setOrderStatus(source.getStatus()); + target.setCurrency(source.getCurrency().getCode()); + //target.setCurrencyModel(source.getCurrency()); + + target.setPaymentType(source.getPaymentType()); + target.setPaymentModule(source.getPaymentModuleCode()); + target.setShippingModule(source.getShippingModuleCode()); + + if(source.getMerchant()!=null) { +/* ReadableMerchantStorePopulator merchantPopulator = new ReadableMerchantStorePopulator(); + merchantPopulator.setCountryService(countryService); + merchantPopulator.setFilePath(filePath); + merchantPopulator.setZoneService(zoneService);*/ + ReadableMerchantStore readableStore = + readableMerchantStorePopulator.populate(source.getMerchant(), null, store, source.getMerchant().getDefaultLanguage()); + target.setStore(readableStore); + } + + + if(source.getCustomerAgreement()!=null) { + target.setCustomerAgreed(source.getCustomerAgreement()); + } + if(source.getConfirmedAddress()!=null) { + target.setConfirmedAddress(source.getConfirmedAddress()); + } + + com.salesmanager.shop.model.order.total.OrderTotal taxTotal = null; + com.salesmanager.shop.model.order.total.OrderTotal shippingTotal = null; + + + if(source.getBilling()!=null) { + ReadableBilling address = new ReadableBilling(); + address.setEmail(source.getCustomerEmailAddress()); + address.setCity(source.getBilling().getCity()); + address.setAddress(source.getBilling().getAddress()); + address.setCompany(source.getBilling().getCompany()); + address.setFirstName(source.getBilling().getFirstName()); + address.setLastName(source.getBilling().getLastName()); + address.setPostalCode(source.getBilling().getPostalCode()); + address.setPhone(source.getBilling().getTelephone()); + if(source.getBilling().getCountry()!=null) { + address.setCountry(source.getBilling().getCountry().getIsoCode()); + } + if(source.getBilling().getZone()!=null) { + address.setZone(source.getBilling().getZone().getCode()); + } + + target.setBilling(address); + } + + if(source.getOrderAttributes()!=null && source.getOrderAttributes().size()>0) { + for(OrderAttribute attr : source.getOrderAttributes()) { + com.salesmanager.shop.model.order.OrderAttribute a = new com.salesmanager.shop.model.order.OrderAttribute(); + a.setKey(attr.getKey()); + a.setValue(attr.getValue()); + target.getAttributes().add(a); + } + } + + if(source.getDelivery()!=null) { + ReadableDelivery address = new ReadableDelivery(); + address.setCity(source.getDelivery().getCity()); + address.setAddress(source.getDelivery().getAddress()); + address.setCompany(source.getDelivery().getCompany()); + address.setFirstName(source.getDelivery().getFirstName()); + address.setLastName(source.getDelivery().getLastName()); + address.setPostalCode(source.getDelivery().getPostalCode()); + address.setPhone(source.getDelivery().getTelephone()); + if(source.getDelivery().getCountry()!=null) { + address.setCountry(source.getDelivery().getCountry().getIsoCode()); + } + if(source.getDelivery().getZone()!=null) { + address.setZone(source.getDelivery().getZone().getCode()); + } + + target.setDelivery(address); + } + + List totals = new ArrayList(); + for(OrderTotal t : source.getOrderTotal()) { + if(t.getOrderTotalType()==null) { + continue; + } + if(t.getOrderTotalType().name().equals(OrderTotalType.TOTAL.name())) { + com.salesmanager.shop.model.order.total.OrderTotal totalTotal = createTotal(t); + target.setTotal(totalTotal); + totals.add(totalTotal); + } + else if(t.getOrderTotalType().name().equals(OrderTotalType.TAX.name())) { + com.salesmanager.shop.model.order.total.OrderTotal totalTotal = createTotal(t); + if(taxTotal==null) { + taxTotal = totalTotal; + } else { + BigDecimal v = taxTotal.getValue(); + v = v.add(totalTotal.getValue()); + taxTotal.setValue(v); + } + target.setTax(totalTotal); + totals.add(totalTotal); + } + else if(t.getOrderTotalType().name().equals(OrderTotalType.SHIPPING.name())) { + com.salesmanager.shop.model.order.total.OrderTotal totalTotal = createTotal(t); + if(shippingTotal==null) { + shippingTotal = totalTotal; + } else { + BigDecimal v = shippingTotal.getValue(); + v = v.add(totalTotal.getValue()); + shippingTotal.setValue(v); + } + target.setShipping(totalTotal); + totals.add(totalTotal); + } + else if(t.getOrderTotalType().name().equals(OrderTotalType.HANDLING.name())) { + com.salesmanager.shop.model.order.total.OrderTotal totalTotal = createTotal(t); + if(shippingTotal==null) { + shippingTotal = totalTotal; + } else { + BigDecimal v = shippingTotal.getValue(); + v = v.add(totalTotal.getValue()); + shippingTotal.setValue(v); + } + target.setShipping(totalTotal); + totals.add(totalTotal); + } + else if(t.getOrderTotalType().name().equals(OrderTotalType.SUBTOTAL.name())) { + com.salesmanager.shop.model.order.total.OrderTotal subTotal = createTotal(t); + totals.add(subTotal); + + } + else { + com.salesmanager.shop.model.order.total.OrderTotal otherTotal = createTotal(t); + totals.add(otherTotal); + } + } + + target.setTotals(totals); + + return target; + } + + private com.salesmanager.shop.model.order.total.OrderTotal createTotal(OrderTotal t) { + com.salesmanager.shop.model.order.total.OrderTotal totalTotal = new com.salesmanager.shop.model.order.total.OrderTotal(); + totalTotal.setCode(t.getOrderTotalCode()); + totalTotal.setId(t.getId()); + totalTotal.setModule(t.getModule()); + totalTotal.setOrder(t.getSortOrder()); + totalTotal.setValue(t.getValue()); + return totalTotal; + } + + @Override + protected ReadableOrder createTarget() { + + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableOrderProductDownloadPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableOrderProductDownloadPopulator.java new file mode 100755 index 0000000000..978ca500ff --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableOrderProductDownloadPopulator.java @@ -0,0 +1,39 @@ +package com.salesmanager.shop.populator.order; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.orderproduct.OrderProductDownload; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.shop.model.order.ReadableOrderProductDownload; + +public class ReadableOrderProductDownloadPopulator extends + AbstractDataPopulator { + + @Override + public ReadableOrderProductDownload populate(OrderProductDownload source, + ReadableOrderProductDownload target, MerchantStore store, + Language language) throws ConversionException { + try { + + target.setProductName(source.getOrderProduct().getProductName()); + target.setDownloadCount(source.getDownloadCount()); + target.setDownloadExpiryDays(source.getMaxdays()); + target.setId(source.getId()); + target.setFileName(source.getOrderProductFilename()); + target.setOrderId(source.getOrderProduct().getOrder().getId()); + + return target; + + } catch(Exception e) { + throw new ConversionException(e); + } + } + + @Override + protected ReadableOrderProductDownload createTarget() { + return new ReadableOrderProductDownload(); + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableOrderProductPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableOrderProductPopulator.java new file mode 100755 index 0000000000..54bb5f9da6 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableOrderProductPopulator.java @@ -0,0 +1,162 @@ +package com.salesmanager.shop.populator.order; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.orderproduct.OrderProduct; +import com.salesmanager.core.model.order.orderproduct.OrderProductAttribute; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.model.order.ReadableOrderProduct; +import com.salesmanager.shop.model.order.ReadableOrderProductAttribute; +import com.salesmanager.shop.populator.catalog.ReadableProductPopulator; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.utils.ImageFilePath; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * Use mappers + * @author carlsamson + * + */ +@Deprecated +public class ReadableOrderProductPopulator extends + AbstractDataPopulator { + + private ProductService productService; + private PricingService pricingService; + private ImageFilePath imageUtils; + + + + public ImageFilePath getimageUtils() { + return imageUtils; + } + + public void setimageUtils(ImageFilePath imageUtils) { + this.imageUtils = imageUtils; + } + + @Override + public ReadableOrderProduct populate(OrderProduct source, + ReadableOrderProduct target, MerchantStore store, Language language) + throws ConversionException { + + Validate.notNull(productService,"Requires ProductService"); + Validate.notNull(pricingService,"Requires PricingService"); + Validate.notNull(imageUtils,"Requires imageUtils"); + target.setId(source.getId()); + target.setOrderedQuantity(source.getProductQuantity()); + try { + target.setPrice(pricingService.getDisplayAmount(source.getOneTimeCharge(), store)); + } catch(Exception e) { + throw new ConversionException("Cannot convert price",e); + } + target.setProductName(source.getProductName()); + target.setSku(source.getSku()); + + //subtotal = price * quantity + BigDecimal subTotal = source.getOneTimeCharge(); + subTotal = subTotal.multiply(new BigDecimal(source.getProductQuantity())); + + try { + String subTotalPrice = pricingService.getDisplayAmount(subTotal, store); + target.setSubTotal(subTotalPrice); + } catch(Exception e) { + throw new ConversionException("Cannot format price",e); + } + + if(source.getOrderAttributes()!=null) { + List attributes = new ArrayList(); + for(OrderProductAttribute attr : source.getOrderAttributes()) { + ReadableOrderProductAttribute readableAttribute = new ReadableOrderProductAttribute(); + try { + String price = pricingService.getDisplayAmount(attr.getProductAttributePrice(), store); + readableAttribute.setAttributePrice(price); + } catch (ServiceException e) { + throw new ConversionException("Cannot format price",e); + } + + readableAttribute.setAttributeName(attr.getProductAttributeName()); + readableAttribute.setAttributeValue(attr.getProductAttributeValueName()); + attributes.add(readableAttribute); + } + target.setAttributes(attributes); + } + + + String productSku = source.getSku(); + if(!StringUtils.isBlank(productSku)) { + Product product = null; + try { + product = productService.getBySku(productSku, store, language); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + if(product!=null) { + + + + ReadableProductPopulator populator = new ReadableProductPopulator(); + populator.setPricingService(pricingService); + populator.setimageUtils(imageUtils); + + ReadableProduct productProxy = populator.populate(product, new ReadableProduct(), store, language); + target.setProduct(productProxy); + + Set images = product.getImages(); + ProductImage defaultImage = null; + if(images!=null) { + for(ProductImage image : images) { + if(defaultImage==null) { + defaultImage = image; + } + if(image.isDefaultImage()) { + defaultImage = image; + } + } + } + if(defaultImage!=null) { + target.setImage(defaultImage.getProductImage()); + } + } + } + + + return target; + } + + @Override + protected ReadableOrderProduct createTarget() { + + return null; + } + + public ProductService getProductService() { + return productService; + } + + public void setProductService(ProductService productService) { + this.productService = productService; + } + + public PricingService getPricingService() { + return pricingService; + } + + public void setPricingService(PricingService pricingService) { + this.pricingService = pricingService; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableOrderSummaryPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableOrderSummaryPopulator.java new file mode 100755 index 0000000000..589c0a36fd --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableOrderSummaryPopulator.java @@ -0,0 +1,97 @@ +package com.salesmanager.shop.populator.order; + +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.CollectionUtils; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.OrderTotal; +import com.salesmanager.core.model.order.OrderTotalSummary; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.order.ReadableOrderTotalSummary; +import com.salesmanager.shop.model.order.total.ReadableOrderTotal; +import com.salesmanager.shop.utils.LabelUtils; + +public class ReadableOrderSummaryPopulator extends AbstractDataPopulator { + + private static final Logger LOGGER = LoggerFactory + .getLogger(ReadableOrderSummaryPopulator.class); + + private PricingService pricingService; + + private LabelUtils messages; + + + + @Override + public ReadableOrderTotalSummary populate(OrderTotalSummary source, ReadableOrderTotalSummary target, + MerchantStore store, Language language) throws ConversionException { + + Validate.notNull(pricingService,"PricingService must be set"); + Validate.notNull(messages,"LabelUtils must be set"); + + if(target==null) { + target = new ReadableOrderTotalSummary(); + } + + try { + + if(source.getSubTotal() != null) { + target.setSubTotal(pricingService.getDisplayAmount(source.getSubTotal(), store)); + } + if(source.getTaxTotal()!=null) { + target.setTaxTotal(pricingService.getDisplayAmount(source.getTaxTotal(), store)); + } + if(source.getTotal() != null) { + target.setTotal(pricingService.getDisplayAmount(source.getTotal(), store)); + } + + if(!CollectionUtils.isEmpty(source.getTotals())) { + ReadableOrderTotalPopulator orderTotalPopulator = new ReadableOrderTotalPopulator(); + orderTotalPopulator.setMessages(messages); + orderTotalPopulator.setPricingService(pricingService); + for(OrderTotal orderTotal : source.getTotals()) { + ReadableOrderTotal t = new ReadableOrderTotal(); + orderTotalPopulator.populate(orderTotal, t, store, language); + target.getTotals().add(t); + } + } + + + } catch(Exception e) { + LOGGER.error("Error during amount formatting " + e.getMessage()); + throw new ConversionException(e); + } + + return target; + + } + + @Override + protected ReadableOrderTotalSummary createTarget() { + // TODO Auto-generated method stub + return null; + } + + + public PricingService getPricingService() { + return pricingService; + } + + public void setPricingService(PricingService pricingService) { + this.pricingService = pricingService; + } + + public LabelUtils getMessages() { + return messages; + } + + public void setMessages(LabelUtils messages) { + this.messages = messages; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableOrderTotalPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableOrderTotalPopulator.java new file mode 100755 index 0000000000..1852cc6984 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableOrderTotalPopulator.java @@ -0,0 +1,90 @@ +package com.salesmanager.shop.populator.order; + +import java.util.Locale; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.OrderTotal; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.order.total.ReadableOrderTotal; +import com.salesmanager.shop.utils.LabelUtils; +import com.salesmanager.shop.utils.LocaleUtils; + +public class ReadableOrderTotalPopulator extends + AbstractDataPopulator { + + + private PricingService pricingService; + + + private LabelUtils messages; + + + + + @Override + public ReadableOrderTotal populate(OrderTotal source, + ReadableOrderTotal target, MerchantStore store, Language language) + throws ConversionException { + + Validate.notNull(pricingService,"PricingService must be set"); + Validate.notNull(messages,"LabelUtils must be set"); + + Locale locale = LocaleUtils.getLocale(language); + + try { + + target.setCode(source.getOrderTotalCode()); + target.setId(source.getId()); + target.setModule(source.getModule()); + target.setOrder(source.getSortOrder()); + + + target.setTitle(messages.getMessage(source.getOrderTotalCode(), locale, source.getOrderTotalCode())); + target.setText(source.getText()); + + target.setValue(source.getValue()); + target.setTotal(pricingService.getDisplayAmount(source.getValue(), store)); + + if(!StringUtils.isBlank(source.getOrderTotalCode())) { + if(Constants.OT_DISCOUNT_TITLE.equals(source.getOrderTotalCode())) { + target.setDiscounted(true); + } + } + + } catch(Exception e) { + throw new ConversionException(e); + } + + return target; + + } + + @Override + protected ReadableOrderTotal createTarget() { + return new ReadableOrderTotal(); + } + + public PricingService getPricingService() { + return pricingService; + } + + public void setPricingService(PricingService pricingService) { + this.pricingService = pricingService; + } + + public LabelUtils getMessages() { + return messages; + } + + public void setMessages(LabelUtils messages) { + this.messages = messages; + } + +} \ No newline at end of file diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableShippingSummaryPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableShippingSummaryPopulator.java new file mode 100755 index 0000000000..c6fe18638d --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableShippingSummaryPopulator.java @@ -0,0 +1,82 @@ +package com.salesmanager.shop.populator.order; + +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shipping.ShippingSummary; +import com.salesmanager.shop.model.customer.ReadableDelivery; +import com.salesmanager.shop.model.order.shipping.ReadableShippingSummary; + +public class ReadableShippingSummaryPopulator extends + AbstractDataPopulator { + + private PricingService pricingService; + + @Override + public ReadableShippingSummary populate(ShippingSummary source, + ReadableShippingSummary target, MerchantStore store, + Language language) throws ConversionException { + + Validate.notNull(pricingService,"PricingService must be set"); + Validate.notNull(source,"ShippingSummary cannot be null"); + + try { + + target.setShippingQuote(source.isShippingQuote()); + target.setFreeShipping(source.isFreeShipping()); + target.setHandling(source.getHandling()); + target.setShipping(source.getShipping()); + target.setShippingModule(source.getShippingModule()); + target.setShippingOption(source.getShippingOption()); + target.setTaxOnShipping(source.isTaxOnShipping()); + target.setHandlingText(pricingService.getDisplayAmount(source.getHandling(), store)); + target.setShippingText(pricingService.getDisplayAmount(source.getShipping(), store)); + + if(source.getDeliveryAddress()!=null) { + + ReadableDelivery deliveryAddress = new ReadableDelivery(); + deliveryAddress.setAddress(source.getDeliveryAddress().getAddress()); + deliveryAddress.setPostalCode(source.getDeliveryAddress().getPostalCode()); + deliveryAddress.setCity(source.getDeliveryAddress().getCity()); + if(source.getDeliveryAddress().getZone()!=null) { + deliveryAddress.setZone(source.getDeliveryAddress().getZone().getCode()); + } + if(source.getDeliveryAddress().getCountry()!=null) { + deliveryAddress.setCountry(source.getDeliveryAddress().getCountry().getIsoCode()); + } + deliveryAddress.setLatitude(source.getDeliveryAddress().getLatitude()); + deliveryAddress.setLongitude(source.getDeliveryAddress().getLongitude()); + deliveryAddress.setStateProvince(source.getDeliveryAddress().getState()); + + target.setDelivery(deliveryAddress); + } + + + } catch(Exception e) { + throw new ConversionException(e); + } + + return target; + + + } + + @Override + protected ReadableShippingSummary createTarget() { + return new + ReadableShippingSummary(); + } + + public PricingService getPricingService() { + return pricingService; + } + + public void setPricingService(PricingService pricingService) { + this.pricingService = pricingService; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableShopOrderPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableShopOrderPopulator.java new file mode 100755 index 0000000000..58e2536c3a --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ReadableShopOrderPopulator.java @@ -0,0 +1,117 @@ +package com.salesmanager.shop.populator.order; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.shop.model.customer.PersistableCustomer; +import com.salesmanager.shop.model.customer.ReadableCustomer; +import com.salesmanager.shop.model.customer.address.Address; +import com.salesmanager.shop.model.order.ReadableShopOrder; +import com.salesmanager.shop.model.order.ShopOrder; + +public class ReadableShopOrderPopulator extends + AbstractDataPopulator { + + @Override + public ReadableShopOrder populate(ShopOrder source, + ReadableShopOrder target, MerchantStore store, Language language) + throws ConversionException { + + //not that much is required + + + //customer + + try { + + ReadableCustomer customer = new ReadableCustomer(); + PersistableCustomer persistableCustomer = source.getCustomer(); + + + customer.setEmailAddress(persistableCustomer.getEmailAddress()); + if(persistableCustomer.getBilling()!=null) { + Address address = new Address(); + address.setCity(persistableCustomer.getBilling().getCity()); + address.setCompany(persistableCustomer.getBilling().getCompany()); + address.setFirstName(persistableCustomer.getBilling().getFirstName()); + address.setLastName(persistableCustomer.getBilling().getLastName()); + address.setPostalCode(persistableCustomer.getBilling().getPostalCode()); + address.setPhone(persistableCustomer.getBilling().getPhone()); + if(persistableCustomer.getBilling().getCountry()!=null) { + address.setCountry(persistableCustomer.getBilling().getCountry()); + } + if(persistableCustomer.getBilling().getZone()!=null) { + address.setZone(persistableCustomer.getBilling().getZone()); + } + + customer.setBilling(address); + } + + if(persistableCustomer.getDelivery()!=null) { + Address address = new Address(); + address.setCity(persistableCustomer.getDelivery().getCity()); + address.setCompany(persistableCustomer.getDelivery().getCompany()); + address.setFirstName(persistableCustomer.getDelivery().getFirstName()); + address.setLastName(persistableCustomer.getDelivery().getLastName()); + address.setPostalCode(persistableCustomer.getDelivery().getPostalCode()); + address.setPhone(persistableCustomer.getDelivery().getPhone()); + if(persistableCustomer.getDelivery().getCountry()!=null) { + address.setCountry(persistableCustomer.getDelivery().getCountry()); + } + if(persistableCustomer.getDelivery().getZone()!=null) { + address.setZone(persistableCustomer.getDelivery().getZone()); + } + + customer.setDelivery(address); + } + + //TODO if ship to billing enabled, set delivery = billing + + +/* if(persistableCustomer.getAttributes()!=null) { + for(PersistableCustomerAttribute attribute : persistableCustomer.getAttributes()) { + ReadableCustomerAttribute readableAttribute = new ReadableCustomerAttribute(); + readableAttribute.setId(attribute.getId()); + ReadableCustomerOption option = new ReadableCustomerOption(); + option.setId(attribute.getCustomerOption().getId()); + option.setCode(attribute.getCustomerOption()); + + CustomerOptionDescription d = new CustomerOptionDescription(); + d.setDescription(attribute.getCustomerOption().getDescriptionsSettoList().get(0).getDescription()); + d.setName(attribute.getCustomerOption().getDescriptionsSettoList().get(0).getName()); + option.setDescription(d); + + readableAttribute.setCustomerOption(option); + + ReadableCustomerOptionValue optionValue = new ReadableCustomerOptionValue(); + optionValue.setId(attribute.getCustomerOptionValue().getId()); + CustomerOptionValueDescription vd = new CustomerOptionValueDescription(); + vd.setDescription(attribute.getCustomerOptionValue().getDescriptionsSettoList().get(0).getDescription()); + vd.setName(attribute.getCustomerOptionValue().getDescriptionsSettoList().get(0).getName()); + optionValue.setCode(attribute.getCustomerOptionValue().getCode()); + optionValue.setDescription(vd); + + + readableAttribute.setCustomerOptionValue(optionValue); + customer.getAttributes().add(readableAttribute); + } + }*/ + + target.setCustomer(customer); + + } catch (Exception e) { + throw new ConversionException(e); + } + + + + return target; + } + + @Override + protected ReadableShopOrder createTarget() { + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ShoppingCartItemPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ShoppingCartItemPopulator.java new file mode 100755 index 0000000000..6f7d73d153 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/ShoppingCartItemPopulator.java @@ -0,0 +1,98 @@ +package com.salesmanager.shop.populator.order; + +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService; +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.core.business.services.shoppingcart.ShoppingCartService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.shop.model.order.PersistableOrderProduct; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; + +public class ShoppingCartItemPopulator extends + AbstractDataPopulator { + + + private ProductService productService; + private ProductAttributeService productAttributeService; + private ShoppingCartService shoppingCartService; + + @Override + public ShoppingCartItem populate(PersistableOrderProduct source, /** TODO: Fix, target not used possible future bug ! **/ShoppingCartItem target, + MerchantStore store, Language language) + throws ConversionException { + Validate.notNull(productService, "Requires to set productService"); + Validate.notNull(productAttributeService, "Requires to set productAttributeService"); + Validate.notNull(shoppingCartService, "Requires to set shoppingCartService"); + + Product product = null; + try { + product = productService.getBySku(source.getSku(), store, language); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + if(product==null ) { + throw new ResourceNotFoundException("No product found for sku [" + source.getSku() +"]"); + } + + if(source.getAttributes()!=null) { + + for(com.salesmanager.shop.model.catalog.product.attribute.ProductAttribute attr : source.getAttributes()) { + ProductAttribute attribute = productAttributeService.getById(attr.getId()); + if(attribute==null) { + throw new ConversionException("ProductAttribute with id " + attr.getId() + " is null"); + } + if(attribute.getProduct().getId().longValue()!=source.getProduct().getId().longValue()) { + throw new ConversionException("ProductAttribute with id " + attr.getId() + " is not assigned to Product id " + source.getProduct().getId()); + } + product.getAttributes().add(attribute); + } + } + + try { + return shoppingCartService.populateShoppingCartItem(product, store); + } catch (ServiceException e) { + throw new ConversionException(e); + } + + } + + @Override + protected ShoppingCartItem createTarget() { + // TODO Auto-generated method stub + return null; + } + + public void setProductAttributeService(ProductAttributeService productAttributeService) { + this.productAttributeService = productAttributeService; + } + + public ProductAttributeService getProductAttributeService() { + return productAttributeService; + } + + public void setProductService(ProductService productService) { + this.productService = productService; + } + + public ProductService getProductService() { + return productService; + } + + public void setShoppingCartService(ShoppingCartService shoppingCartService) { + this.shoppingCartService = shoppingCartService; + } + + public ShoppingCartService getShoppingCartService() { + return shoppingCartService; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/order/transaction/PersistablePaymentPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/transaction/PersistablePaymentPopulator.java new file mode 100755 index 0000000000..80a89e2fb4 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/transaction/PersistablePaymentPopulator.java @@ -0,0 +1,67 @@ +package com.salesmanager.shop.populator.order.transaction; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.payments.Payment; +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.core.model.payments.TransactionType; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.order.transaction.PersistablePayment; + +public class PersistablePaymentPopulator extends AbstractDataPopulator { + + + PricingService pricingService; + + + + @Override + public Payment populate(PersistablePayment source, Payment target, MerchantStore store, Language language) + throws ConversionException { + + Validate.notNull(source,"PersistablePayment cannot be null"); + Validate.notNull(pricingService,"pricingService must be set"); + if(target == null) { + target = new Payment(); + } + + try { + + target.setAmount(pricingService.getAmount(source.getAmount())); + target.setModuleName(source.getPaymentModule()); + target.setPaymentType(PaymentType.valueOf(source.getPaymentType())); + target.setTransactionType(TransactionType.valueOf(source.getTransactionType())); + + Map metadata = new HashMap(); + metadata.put("paymentToken", source.getPaymentToken()); + target.setPaymentMetaData(metadata); + + return target; + + } catch(Exception e) { + throw new ConversionException(e); + } + } + + @Override + protected Payment createTarget() { + // TODO Auto-generated method stub + return null; + } + + public PricingService getPricingService() { + return pricingService; + } + + public void setPricingService(PricingService pricingService) { + this.pricingService = pricingService; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/order/transaction/PersistableTransactionPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/transaction/PersistableTransactionPopulator.java new file mode 100755 index 0000000000..508f1204b5 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/transaction/PersistableTransactionPopulator.java @@ -0,0 +1,89 @@ +package com.salesmanager.shop.populator.order.transaction; + +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.order.OrderService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.payments.TransactionType; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.order.transaction.PersistableTransaction; +import com.salesmanager.shop.utils.DateUtil; + +public class PersistableTransactionPopulator extends AbstractDataPopulator { + + private OrderService orderService; + private PricingService pricingService; + + @Override + public Transaction populate(PersistableTransaction source, Transaction target, MerchantStore store, + Language language) throws ConversionException { + + Validate.notNull(source,"PersistableTransaction must not be null"); + Validate.notNull(orderService,"OrderService must not be null"); + Validate.notNull(pricingService,"OrderService must not be null"); + + if(target == null) { + target = new Transaction(); + } + + + try { + + + target.setAmount(pricingService.getAmount(source.getAmount())); + target.setDetails(source.getDetails()); + target.setPaymentType(PaymentType.valueOf(source.getPaymentType())); + target.setTransactionType(TransactionType.valueOf(source.getTransactionType())); + target.setTransactionDate(DateUtil.getDate(source.getTransactionDate())); + + if(source.getOrderId()!=null && source.getOrderId().longValue() > 0) { + Order order = orderService.getById(source.getOrderId()); +/* if(source.getCustomerId() == null) { + throw new ConversionException("Cannot add a transaction for an Order without specyfing the customer"); + }*/ + + if(order == null) { + throw new ConversionException("Order with id " + source.getOrderId() + "does not exist"); + } + target.setOrder(order); + } + + return target; + + + + } catch(Exception e) { + throw new ConversionException(e); + } + + } + + @Override + protected Transaction createTarget() { + // TODO Auto-generated method stub + return null; + } + + public OrderService getOrderService() { + return orderService; + } + + public void setOrderService(OrderService orderService) { + this.orderService = orderService; + } + + public PricingService getPricingService() { + return pricingService; + } + + public void setPricingService(PricingService pricingService) { + this.pricingService = pricingService; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/order/transaction/ReadableTransactionPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/transaction/ReadableTransactionPopulator.java new file mode 100755 index 0000000000..d11306fe79 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/order/transaction/ReadableTransactionPopulator.java @@ -0,0 +1,83 @@ +package com.salesmanager.shop.populator.order.transaction; + +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.order.OrderService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.order.transaction.ReadableTransaction; +import com.salesmanager.shop.utils.DateUtil; + + +public class ReadableTransactionPopulator extends AbstractDataPopulator { + + + private OrderService orderService; + private PricingService pricingService; + + @Override + public ReadableTransaction populate(Transaction source, ReadableTransaction target, MerchantStore store, + Language language) throws ConversionException { + + + Validate.notNull(source,"PersistableTransaction must not be null"); + Validate.notNull(orderService,"OrderService must not be null"); + Validate.notNull(pricingService,"OrderService must not be null"); + + if(target == null) { + target = new ReadableTransaction(); + } + + + try { + + + target.setAmount(pricingService.getDisplayAmount(source.getAmount(), store)); + target.setDetails(source.getDetails()); + target.setPaymentType(source.getPaymentType()); + target.setTransactionType(source.getTransactionType()); + target.setTransactionDate(DateUtil.formatDate(source.getTransactionDate())); + target.setId(source.getId()); + + if(source.getOrder() != null) { + target.setOrderId(source.getOrder().getId()); + + } + + return target; + + + + } catch(Exception e) { + throw new ConversionException(e); + } + + } + + @Override + protected ReadableTransaction createTarget() { + // TODO Auto-generated method stub + return null; + } + + public OrderService getOrderService() { + return orderService; + } + + public void setOrderService(OrderService orderService) { + this.orderService = orderService; + } + + public PricingService getPricingService() { + return pricingService; + } + + public void setPricingService(PricingService pricingService) { + this.pricingService = pricingService; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/references/ReadableCountryPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/references/ReadableCountryPopulator.java new file mode 100755 index 0000000000..d0b009d9b4 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/references/ReadableCountryPopulator.java @@ -0,0 +1,58 @@ +package com.salesmanager.shop.populator.references; + +import org.apache.commons.collections4.CollectionUtils; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.core.model.reference.zone.ZoneDescription; +import com.salesmanager.shop.model.references.ReadableCountry; +import com.salesmanager.shop.model.references.ReadableZone; + +public class ReadableCountryPopulator extends AbstractDataPopulator { + + @Override + public ReadableCountry populate(Country source, ReadableCountry target, MerchantStore store, Language language) + throws ConversionException { + + if(target==null) { + target = new ReadableCountry(); + } + + target.setId(new Long(source.getId())); + target.setCode(source.getIsoCode()); + target.setSupported(source.getSupported()); + if(!CollectionUtils.isEmpty(source.getDescriptions())) { + target.setName(source.getDescriptions().iterator().next().getName()); + } + + if(!CollectionUtils.isEmpty(source.getZones())) { + for(Zone z : source.getZones()) { + ReadableZone readableZone = new ReadableZone(); + readableZone.setCountryCode(target.getCode()); + readableZone.setId(z.getId()); + if(!CollectionUtils.isEmpty(z.getDescriptions())) { + for(ZoneDescription d : z.getDescriptions()) { + if(d.getLanguage().getId() == language.getId()) { + readableZone.setName(d.getName()); + continue; + } + } + } + target.getZones().add(readableZone); + } + } + + return target; + } + + @Override + protected ReadableCountry createTarget() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/references/ReadableZonePopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/references/ReadableZonePopulator.java new file mode 100755 index 0000000000..1af30c87be --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/references/ReadableZonePopulator.java @@ -0,0 +1,45 @@ +package com.salesmanager.shop.populator.references; + +import org.apache.commons.collections4.CollectionUtils; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.core.model.reference.zone.ZoneDescription; +import com.salesmanager.shop.model.references.ReadableZone; + +public class ReadableZonePopulator extends AbstractDataPopulator { + + @Override + public ReadableZone populate(Zone source, ReadableZone target, MerchantStore store, Language language) + throws ConversionException { + if(target==null) { + target = new ReadableZone(); + } + + target.setId(source.getId()); + target.setCode(source.getCode()); + target.setCountryCode(source.getCountry().getIsoCode()); + + if(!CollectionUtils.isEmpty(source.getDescriptions())) { + for(ZoneDescription d : source.getDescriptions()) { + if(d.getLanguage().getId() == language.getId()) { + target.setName(d.getName()); + continue; + } + } + } + + return target; + + } + + @Override + protected ReadableZone createTarget() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/security/ReadablePermissionPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/security/ReadablePermissionPopulator.java new file mode 100755 index 0000000000..3d4b405f26 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/security/ReadablePermissionPopulator.java @@ -0,0 +1,25 @@ +package com.salesmanager.shop.populator.security; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.user.Permission; +import com.salesmanager.shop.model.security.ReadablePermission; + +public class ReadablePermissionPopulator extends AbstractDataPopulator { + + @Override + public ReadablePermission populate(Permission source, ReadablePermission target, + MerchantStore store, Language language) throws ConversionException { + // TODO Auto-generated method stub + return null; + } + + @Override + protected ReadablePermission createTarget() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/shoppingCart/ShoppingCartDataPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/shoppingCart/ShoppingCartDataPopulator.java new file mode 100755 index 0000000000..b68c3c842f --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/shoppingCart/ShoppingCartDataPopulator.java @@ -0,0 +1,234 @@ +/** + * + */ +package com.salesmanager.shop.populator.shoppingCart; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.beanutils.ConversionException; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.shoppingcart.ShoppingCartCalculationService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValueDescription; +import com.salesmanager.core.model.catalog.product.description.ProductDescription; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.OrderSummary; +import com.salesmanager.core.model.order.OrderTotalSummary; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.shop.model.order.total.OrderTotal; +import com.salesmanager.shop.model.shoppingcart.ShoppingCartAttribute; +import com.salesmanager.shop.model.shoppingcart.ShoppingCartData; +import com.salesmanager.shop.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.shop.utils.ImageFilePath; + + +/** + * @author Umesh A + * + */ + +@Deprecated +public class ShoppingCartDataPopulator extends AbstractDataPopulator +{ + + private static final Logger LOG = LoggerFactory.getLogger(ShoppingCartDataPopulator.class); + + private PricingService pricingService; + + private ShoppingCartCalculationService shoppingCartCalculationService; + + private ImageFilePath imageUtils; + + public ImageFilePath getimageUtils() { + return imageUtils; + } + + + + + public void setimageUtils(ImageFilePath imageUtils) { + this.imageUtils = imageUtils; + } + + + + @Override + public ShoppingCartData createTarget() + { + + return new ShoppingCartData(); + } + + + + public ShoppingCartCalculationService getOrderService() { + return shoppingCartCalculationService; + } + + + + public PricingService getPricingService() { + return pricingService; + } + + + @Override + public ShoppingCartData populate(final ShoppingCart shoppingCart, + final ShoppingCartData cart, final MerchantStore store, final Language language) { + + Validate.notNull(shoppingCart, "Requires ShoppingCart"); + Validate.notNull(language, "Requires Language not null"); + int cartQuantity = 0; + cart.setCode(shoppingCart.getShoppingCartCode()); + Set items = shoppingCart.getLineItems(); + List shoppingCartItemsList=Collections.emptyList(); + try{ + if(items!=null) { + shoppingCartItemsList=new ArrayList(); + for(com.salesmanager.core.model.shoppingcart.ShoppingCartItem item : items) { + + ShoppingCartItem shoppingCartItem = new ShoppingCartItem(); + shoppingCartItem.setCode(cart.getCode()); + shoppingCartItem.setSku(item.getProduct().getSku()); + shoppingCartItem.setProductVirtual(item.isProductVirtual()); + + shoppingCartItem.setId(item.getId()); + + String itemName = item.getProduct().getProductDescription().getName(); + if(!CollectionUtils.isEmpty(item.getProduct().getDescriptions())) { + for(ProductDescription productDescription : item.getProduct().getDescriptions()) { + if(language != null && language.getId().intValue() == productDescription.getLanguage().getId().intValue()) { + itemName = productDescription.getName(); + break; + } + } + } + + shoppingCartItem.setName(itemName); + + shoppingCartItem.setPrice(pricingService.getDisplayAmount(item.getItemPrice(),store)); + shoppingCartItem.setQuantity(item.getQuantity()); + + + cartQuantity = cartQuantity + item.getQuantity(); + + shoppingCartItem.setProductPrice(item.getItemPrice()); + shoppingCartItem.setSubTotal(pricingService.getDisplayAmount(item.getSubTotal(), store)); + ProductImage image = item.getProduct().getProductImage(); + if(image!=null && imageUtils!=null) { + String imagePath = imageUtils.buildProductImageUtils(store, item.getProduct().getSku(), image.getProductImage()); + shoppingCartItem.setImage(imagePath); + } + Set attributes = item.getAttributes(); + if(attributes!=null) { + List cartAttributes = new ArrayList(); + for(com.salesmanager.core.model.shoppingcart.ShoppingCartAttributeItem attribute : attributes) { + ShoppingCartAttribute cartAttribute = new ShoppingCartAttribute(); + cartAttribute.setId(attribute.getId()); + cartAttribute.setAttributeId(attribute.getProductAttributeId()); + cartAttribute.setOptionId(attribute.getProductAttribute().getProductOption().getId()); + cartAttribute.setOptionValueId(attribute.getProductAttribute().getProductOptionValue().getId()); + List optionDescriptions = attribute.getProductAttribute().getProductOption().getDescriptionsSettoList(); + List optionValueDescriptions = attribute.getProductAttribute().getProductOptionValue().getDescriptionsSettoList(); + if(!CollectionUtils.isEmpty(optionDescriptions) && !CollectionUtils.isEmpty(optionValueDescriptions)) { + + String optionName = optionDescriptions.get(0).getName(); + String optionValue = optionValueDescriptions.get(0).getName(); + + for(ProductOptionDescription optionDescription : optionDescriptions) { + if(optionDescription.getLanguage() != null && optionDescription.getLanguage().getId().intValue() == language.getId().intValue()) { + optionName = optionDescription.getName(); + break; + } + } + + for(ProductOptionValueDescription optionValueDescription : optionValueDescriptions) { + if(optionValueDescription.getLanguage() != null && optionValueDescription.getLanguage().getId().intValue() == language.getId().intValue()) { + optionValue = optionValueDescription.getName(); + break; + } + } + cartAttribute.setOptionName(optionName); + cartAttribute.setOptionValue(optionValue); + cartAttributes.add(cartAttribute); + } + } + shoppingCartItem.setShoppingCartAttributes(cartAttributes); + } + shoppingCartItemsList.add(shoppingCartItem); + } + } + if(CollectionUtils.isNotEmpty(shoppingCartItemsList)){ + cart.setShoppingCartItems(shoppingCartItemsList); + } + + if(shoppingCart.getOrderId() != null) { + cart.setOrderId(shoppingCart.getOrderId()); + } + + OrderSummary summary = new OrderSummary(); + List productsList = new ArrayList(); + productsList.addAll(shoppingCart.getLineItems()); + summary.setProducts(productsList.stream().filter(p -> p.getProduct().isAvailable()).collect(Collectors.toList())); + OrderTotalSummary orderSummary = shoppingCartCalculationService.calculate(shoppingCart,store, language ); + + if(CollectionUtils.isNotEmpty(orderSummary.getTotals())) { + List totals = new ArrayList(); + for(com.salesmanager.core.model.order.OrderTotal t : orderSummary.getTotals()) { + OrderTotal total = new OrderTotal(); + total.setCode(t.getOrderTotalCode()); + total.setText(t.getText()); + total.setValue(t.getValue()); + totals.add(total); + } + cart.setTotals(totals); + } + + cart.setSubTotal(pricingService.getDisplayAmount(orderSummary.getSubTotal(), store)); + cart.setTotal(pricingService.getDisplayAmount(orderSummary.getTotal(), store)); + cart.setQuantity(cartQuantity); + cart.setId(shoppingCart.getId()); + } + catch(ServiceException ex){ + LOG.error( "Error while converting cart Model to cart Data.."+ex ); + throw new ConversionException( "Unable to create cart data", ex ); + } + return cart; + + + }; + + + + + + public void setPricingService(final PricingService pricingService) { + this.pricingService = pricingService; + } + + + + + + + public void setShoppingCartCalculationService(final ShoppingCartCalculationService shoppingCartCalculationService) { + this.shoppingCartCalculationService = shoppingCartCalculationService; + } + + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/shoppingCart/ShoppingCartModelPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/shoppingCart/ShoppingCartModelPopulator.java new file mode 100755 index 0000000000..7cef192c29 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/shoppingCart/ShoppingCartModelPopulator.java @@ -0,0 +1,282 @@ +/** + * + */ +package com.salesmanager.shop.populator.shoppingCart; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.beanutils.ConversionException; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService; +import com.salesmanager.core.business.services.shoppingcart.ShoppingCartService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.shop.model.shoppingcart.ShoppingCartAttribute; +import com.salesmanager.shop.model.shoppingcart.ShoppingCartData; +import com.salesmanager.shop.model.shoppingcart.ShoppingCartItem; + +/** + * @author Umesh A + */ + +@Service(value="shoppingCartModelPopulator") +public class ShoppingCartModelPopulator + extends AbstractDataPopulator +{ + + private static final Logger LOG = LoggerFactory.getLogger(ShoppingCartModelPopulator.class); + + private ShoppingCartService shoppingCartService; + + private Customer customer; + + public ShoppingCartService getShoppingCartService() { + return shoppingCartService; + } + + + public void setShoppingCartService(ShoppingCartService shoppingCartService) { + this.shoppingCartService = shoppingCartService; + } + + + private ProductService productService; + + + public ProductService getProductService() { + return productService; + } + + + public void setProductService(ProductService productService) { + this.productService = productService; + } + + + private ProductAttributeService productAttributeService; + + + public ProductAttributeService getProductAttributeService() { + return productAttributeService; + } + + + public void setProductAttributeService( + ProductAttributeService productAttributeService) { + this.productAttributeService = productAttributeService; + } + + + @Override + public ShoppingCart populate(ShoppingCartData shoppingCart,ShoppingCart cartMdel,final MerchantStore store, Language language) + { + + + // if id >0 get the original from the database, override products + try{ + if ( shoppingCart.getId() > 0 && StringUtils.isNotBlank( shoppingCart.getCode())) + { + cartMdel = shoppingCartService.getByCode( shoppingCart.getCode(), store ); + if(cartMdel==null){ + cartMdel=new ShoppingCart(); + cartMdel.setShoppingCartCode( shoppingCart.getCode() ); + cartMdel.setMerchantStore( store ); + if ( customer != null ) + { + cartMdel.setCustomerId( customer.getId() ); + } + shoppingCartService.create( cartMdel ); + } + } + else + { + cartMdel.setShoppingCartCode( shoppingCart.getCode() ); + cartMdel.setMerchantStore( store ); + if ( customer != null ) + { + cartMdel.setCustomerId( customer.getId() ); + } + shoppingCartService.create( cartMdel ); + } + + List items = shoppingCart.getShoppingCartItems(); + Set newItems = + new HashSet(); + if ( items != null && items.size() > 0 ) + { + for ( ShoppingCartItem item : items ) + { + + Set cartItems = cartMdel.getLineItems(); + if ( cartItems != null && cartItems.size() > 0 ) + { + + for ( com.salesmanager.core.model.shoppingcart.ShoppingCartItem dbItem : cartItems ) + { + if ( dbItem.getId().longValue() == item.getId() ) + { + dbItem.setQuantity( item.getQuantity() ); + // compare attributes + Set attributes = + dbItem.getAttributes(); + Set newAttributes = + new HashSet(); + List cartAttributes = item.getShoppingCartAttributes(); + if ( !CollectionUtils.isEmpty( cartAttributes ) ) + { + for ( ShoppingCartAttribute attribute : cartAttributes ) + { + for ( com.salesmanager.core.model.shoppingcart.ShoppingCartAttributeItem dbAttribute : attributes ) + { + if ( dbAttribute.getId().longValue() == attribute.getId() ) + { + newAttributes.add( dbAttribute ); + } + } + } + + dbItem.setAttributes( newAttributes ); + } + else + { + dbItem.removeAllAttributes(); + } + newItems.add( dbItem ); + } + } + } + else + {// create new item + com.salesmanager.core.model.shoppingcart.ShoppingCartItem cartItem = + createCartItem( cartMdel, item, store ); + Set lineItems = + cartMdel.getLineItems(); + if ( lineItems == null ) + { + lineItems = new HashSet(); + cartMdel.setLineItems( lineItems ); + } + lineItems.add( cartItem ); + shoppingCartService.update( cartMdel ); + } + }// end for + }// end if + }catch(ServiceException se){ + LOG.error( "Error while converting cart data to cart model.."+se ); + throw new ConversionException( "Unable to create cart model", se ); + } + catch (Exception ex){ + LOG.error( "Error while converting cart data to cart model.."+ex ); + throw new ConversionException( "Unable to create cart model", ex ); + } + + return cartMdel; + } + + + private com.salesmanager.core.model.shoppingcart.ShoppingCartItem createCartItem( + com.salesmanager.core.model.shoppingcart.ShoppingCart cart, + ShoppingCartItem shoppingCartItem, + MerchantStore store ) throws Exception + { + + + + Product product = productService.getBySku(shoppingCartItem.getSku(), store, store.getDefaultLanguage()); + if ( product == null ) + { + throw new Exception( "Item with sku " + shoppingCartItem.getSku() + " does not exist" ); + } + + if ( product.getMerchantStore().getId().intValue() != store.getId().intValue() ) + { + throw new Exception( "Item with sku " + shoppingCartItem.getSku() + " does not belong to merchant " + + store.getId() ); + } + + + + + + com.salesmanager.core.model.shoppingcart.ShoppingCartItem item = + new com.salesmanager.core.model.shoppingcart.ShoppingCartItem( cart, product ); + item.setQuantity( shoppingCartItem.getQuantity() ); + item.setItemPrice( shoppingCartItem.getProductPrice() ); + item.setShoppingCart( cart ); + item.setSku(shoppingCartItem.getSku()); + + // attributes + List cartAttributes = shoppingCartItem.getShoppingCartAttributes(); + if ( !CollectionUtils.isEmpty( cartAttributes ) ) + { + Set newAttributes = + new HashSet(); + for ( ShoppingCartAttribute attribute : cartAttributes ) + { + ProductAttribute productAttribute = productAttributeService.getById( attribute.getAttributeId() ); + if ( productAttribute != null + && productAttribute.getProduct().getId().longValue() == product.getId().longValue() ) + { + com.salesmanager.core.model.shoppingcart.ShoppingCartAttributeItem attributeItem = + new com.salesmanager.core.model.shoppingcart.ShoppingCartAttributeItem( item, + productAttribute ); + if ( attribute.getAttributeId() > 0 ) + { + attributeItem.setId( attribute.getId() ); + } + item.addAttributes( attributeItem ); + //newAttributes.add( attributeItem ); + } + + } + + //item.setAttributes( newAttributes ); + } + + return item; + + } + + + + + @Override + protected ShoppingCart createTarget() + { + + return new ShoppingCart(); + } + + + public Customer getCustomer() { + return customer; + } + + + public void setCustomer(Customer customer) { + this.customer = customer; + } + + + + + + + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/store/PersistableMerchantStorePopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/store/PersistableMerchantStorePopulator.java new file mode 100755 index 0000000000..64dec7bb28 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/store/PersistableMerchantStorePopulator.java @@ -0,0 +1,198 @@ +package com.salesmanager.shop.populator.store; + +import java.util.Date; +import java.util.List; + +import javax.inject.Inject; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.merchant.MerchantStoreService; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.currency.CurrencyService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.services.reference.zone.ZoneService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.currency.Currency; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.shop.model.references.PersistableAddress; +import com.salesmanager.shop.model.store.PersistableMerchantStore; +import com.salesmanager.shop.utils.DateUtil; + +@Component +public class PersistableMerchantStorePopulator extends AbstractDataPopulator { + + @Inject + private CountryService countryService; + @Inject + private ZoneService zoneService; + @Inject + private LanguageService languageService; + @Inject + private CurrencyService currencyService; + @Inject + private MerchantStoreService merchantStoreService; + + + @Override + public MerchantStore populate(PersistableMerchantStore source, MerchantStore target, MerchantStore store, + Language language) throws ConversionException { + + Validate.notNull(source, "PersistableMerchantStore mst not be null"); + + if(target == null) { + target = new MerchantStore(); + } + + target.setCode(source.getCode()); + if(source.getId()!=0) { + target.setId(source.getId()); + } + + if(store.getStoreLogo()!=null) { + target.setStoreLogo(store.getStoreLogo()); + } + + if(!StringUtils.isEmpty(source.getInBusinessSince())) { + try { + Date dt = DateUtil.getDate(source.getInBusinessSince()); + target.setInBusinessSince(dt); + } catch(Exception e) { + throw new ConversionException("Cannot parse date [" + source.getInBusinessSince() + "]",e); + } + } + + if(source.getDimension()!=null) { + target.setSeizeunitcode(source.getDimension().name()); + } + if(source.getWeight()!=null) { + target.setWeightunitcode(source.getWeight().name()); + } + target.setCurrencyFormatNational(source.isCurrencyFormatNational()); + target.setStorename(source.getName()); + target.setStorephone(source.getPhone()); + target.setStoreEmailAddress(source.getEmail()); + target.setUseCache(source.isUseCache()); + target.setRetailer(source.isRetailer()); + + //get parent store + if(!StringUtils.isBlank(source.getRetailerStore())) { + if(source.getRetailerStore().equals(source.getCode())) { + throw new ConversionException("Parent store [" + source.getRetailerStore() + "] cannot be parent of current store"); + } + try { + MerchantStore parent = merchantStoreService.getByCode(source.getRetailerStore()); + if(parent == null) { + throw new ConversionException("Parent store [" + source.getRetailerStore() + "] does not exist"); + } + target.setParent(parent); + } catch (ServiceException e) { + throw new ConversionException(e); + } + } + + + try { + + if(!StringUtils.isEmpty(source.getDefaultLanguage())) { + Language l = languageService.getByCode(source.getDefaultLanguage()); + target.setDefaultLanguage(l); + } + + if(!StringUtils.isEmpty(source.getCurrency())) { + Currency c = currencyService.getByCode(source.getCurrency()); + target.setCurrency(c); + } else { + target.setCurrency(currencyService.getByCode(Constants.DEFAULT_CURRENCY.getCurrencyCode())); + } + + List languages = source.getSupportedLanguages(); + if(!CollectionUtils.isEmpty(languages)) { + for(String lang : languages) { + Language ll = languageService.getByCode(lang); + target.getLanguages().add(ll); + } + } + + } catch(Exception e) { + throw new ConversionException(e); + } + + //address population + PersistableAddress address = source.getAddress(); + if(address != null) { + Country country; + try { + country = countryService.getByCode(address.getCountry()); + + Zone zone = zoneService.getByCode(address.getStateProvince()); + if(zone != null) { + target.setZone(zone); + } else { + target.setStorestateprovince(address.getStateProvince()); + } + + target.setStoreaddress(address.getAddress()); + target.setStorecity(address.getCity()); + target.setCountry(country); + target.setStorepostalcode(address.getPostalCode()); + + } catch (ServiceException e) { + throw new ConversionException(e); + } + } + + if (StringUtils.isNotEmpty(source.getTemplate())) + target.setStoreTemplate(source.getTemplate()); + + return target; + } + + @Override + protected MerchantStore createTarget() { + // TODO Auto-generated method stub + return null; + } + + public ZoneService getZoneService() { + return zoneService; + } + + public void setZoneService(ZoneService zoneService) { + this.zoneService = zoneService; + } + public CountryService getCountryService() { + return countryService; + } + + public void setCountryService(CountryService countryService) { + this.countryService = countryService; + } + + public LanguageService getLanguageService() { + return languageService; + } + + public void setLanguageService(LanguageService languageService) { + this.languageService = languageService; + } + + public CurrencyService getCurrencyService() { + return currencyService; + } + + public void setCurrencyService(CurrencyService currencyService) { + this.currencyService = currencyService; + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/store/ReadableMerchantStorePopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/store/ReadableMerchantStorePopulator.java new file mode 100755 index 0000000000..7d11f2864e --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/store/ReadableMerchantStorePopulator.java @@ -0,0 +1,187 @@ +package com.salesmanager.shop.populator.store; + + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.services.reference.zone.ZoneService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.shop.model.content.ReadableImage; +import com.salesmanager.shop.model.entity.ReadableAudit; +import com.salesmanager.shop.model.references.MeasureUnit; +import com.salesmanager.shop.model.references.ReadableAddress; +import com.salesmanager.shop.model.references.ReadableLanguage; +import com.salesmanager.shop.model.references.WeightUnit; +import com.salesmanager.shop.model.store.ReadableMerchantStore; +import com.salesmanager.shop.utils.DateUtil; +import com.salesmanager.shop.utils.ImageFilePath; + +/** + * Populates MerchantStore core entity model object + * @author carlsamson + * + */ +@Component +public class ReadableMerchantStorePopulator extends + AbstractDataPopulator { + + protected final Log logger = LogFactory.getLog(getClass()); + + @Autowired + private CountryService countryService; + @Autowired + private ZoneService zoneService; + @Autowired + @Qualifier("img") + private ImageFilePath filePath; + @Autowired + private LanguageService languageService; + + + + @Override + public ReadableMerchantStore populate(MerchantStore source, + ReadableMerchantStore target, MerchantStore store, Language language) + throws ConversionException { + Validate.notNull(countryService,"Must use setter for countryService"); + Validate.notNull(zoneService,"Must use setter for zoneService"); + + if(target == null) { + target = new ReadableMerchantStore(); + } + + target.setId(source.getId()); + target.setCode(source.getCode()); + if(source.getDefaultLanguage() != null) { + target.setDefaultLanguage(source.getDefaultLanguage().getCode()); + } + + target.setCurrency(source.getCurrency().getCode()); + target.setPhone(source.getStorephone()); + + ReadableAddress address = new ReadableAddress(); + address.setAddress(source.getStoreaddress()); + address.setCity(source.getStorecity()); + if(source.getCountry()!=null) { + try { + address.setCountry(source.getCountry().getIsoCode()); + Country c =countryService.getCountriesMap(language).get(source.getCountry().getIsoCode()); + if(c!=null) { + address.setCountry(c.getIsoCode()); + } + } catch (ServiceException e) { + logger.error("Cannot get Country", e); + } + } + + if(source.getParent() != null) { + ReadableMerchantStore parent = populate(source.getParent(), + new ReadableMerchantStore(), source, language); + target.setParent(parent); + } + + if(target.getParent() == null) { + target.setRetailer(true); + } else { + target.setRetailer(source.isRetailer()!=null?source.isRetailer().booleanValue():false); + } + + + target.setDimension(MeasureUnit.valueOf(source.getSeizeunitcode())); + target.setWeight(WeightUnit.valueOf(source.getWeightunitcode())); + + if(source.getZone()!=null) { + address.setStateProvince(source.getZone().getCode()); + try { + Zone z = zoneService.getZones(language).get(source.getZone().getCode()); + address.setStateProvince(z.getCode()); + } catch (ServiceException e) { + logger.error("Cannot get Zone", e); + } + } + + + if(!StringUtils.isBlank(source.getStorestateprovince())) { + address.setStateProvince(source.getStorestateprovince()); + } + + if(!StringUtils.isBlank(source.getStoreLogo())) { + ReadableImage image = new ReadableImage(); + image.setName(source.getStoreLogo()); + if(filePath!=null) { + image.setPath(filePath.buildStoreLogoFilePath(source)); + } + target.setLogo(image); + } + + address.setPostalCode(source.getStorepostalcode()); + + target.setAddress(address); + + target.setCurrencyFormatNational(source.isCurrencyFormatNational()); + target.setEmail(source.getStoreEmailAddress()); + target.setName(source.getStorename()); + target.setId(source.getId()); + target.setInBusinessSince(DateUtil.formatDate(source.getInBusinessSince())); + target.setUseCache(source.isUseCache()); + + if(!CollectionUtils.isEmpty(source.getLanguages())) { + List supported = new ArrayList(); + for(Language lang : source.getLanguages()) { + try { + Language langObject = languageService.getLanguagesMap().get(lang.getCode()); + if(langObject != null) { + ReadableLanguage l = new ReadableLanguage(); + l.setId(langObject.getId()); + l.setCode(langObject.getCode()); + supported.add(l); + } + + } catch (ServiceException e) { + logger.error("Cannot get Language [" + lang.getId() + "]"); + } + + } + target.setSupportedLanguages(supported); + } + + if(source.getAuditSection()!=null) { + ReadableAudit audit = new ReadableAudit(); + if(source.getAuditSection().getDateCreated()!=null) { + audit.setCreated(DateUtil.formatDate(source.getAuditSection().getDateCreated())); + } + if(source.getAuditSection().getDateModified()!=null) { + audit.setModified(DateUtil.formatDate(source.getAuditSection().getDateCreated())); + } + audit.setUser(source.getAuditSection().getModifiedBy()); + target.setReadableAudit(audit); + } + + return target; + } + + @Override + protected ReadableMerchantStore createTarget() { + // TODO Auto-generated method stub + return null; + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/store/ReadableMerchantStorePopulatorWithDetails.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/store/ReadableMerchantStorePopulatorWithDetails.java new file mode 100755 index 0000000000..7c5107a318 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/store/ReadableMerchantStorePopulatorWithDetails.java @@ -0,0 +1,41 @@ +package com.salesmanager.shop.populator.store; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.store.ReadableMerchantStore; + +/** + * Populates MerchantStore core entity model object with more complete details than the traditional ReadableMerchantStorePopulator + * @author rui pereira + * + */ +public class ReadableMerchantStorePopulatorWithDetails extends + ReadableMerchantStorePopulator { + + protected final Log logger = LogFactory.getLog(getClass()); + + @Override + public ReadableMerchantStore populate(MerchantStore source, + ReadableMerchantStore target, MerchantStore store, Language language) + throws ConversionException { + + target = super.populate(source, target, store, language); + + target.setTemplate(source.getStoreTemplate()); + + // TODO Add more as needed + + return target; + } + + @Override + protected ReadableMerchantStore createTarget() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/system/ReadableOptinPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/system/ReadableOptinPopulator.java new file mode 100755 index 0000000000..309241a2cc --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/system/ReadableOptinPopulator.java @@ -0,0 +1,41 @@ +package com.salesmanager.shop.populator.system; + +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.system.optin.Optin; +import com.salesmanager.shop.model.system.ReadableOptin; + +public class ReadableOptinPopulator extends AbstractDataPopulator { + + @Override + public ReadableOptin populate(Optin source, ReadableOptin target, MerchantStore store, Language language) + throws ConversionException { + Validate.notNull(store,"MerchantStore cannot be null"); + Validate.notNull(source,"Optin cannot be null"); + + if(target==null) { + target = new ReadableOptin(); + } + + target.setCode(source.getCode()); + target.setDescription(source.getDescription()); + target.setEndDate(source.getEndDate()); + target.setId(source.getId()); + target.setOptinType(source.getOptinType().name()); + target.setStartDate(source.getStartDate()); + target.setStore(store.getCode()); + + return target; + } + + @Override + protected ReadableOptin createTarget() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/user/PersistableUserPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/user/PersistableUserPopulator.java new file mode 100755 index 0000000000..e21b17b59c --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/user/PersistableUserPopulator.java @@ -0,0 +1,111 @@ +package com.salesmanager.shop.populator.user; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; +import javax.inject.Named; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.merchant.MerchantStoreService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.services.user.GroupService; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.model.user.User; +import com.salesmanager.shop.model.security.PersistableGroup; +import com.salesmanager.shop.model.user.PersistableUser; + + +@Component +public class PersistableUserPopulator extends AbstractDataPopulator { + + @Inject + private LanguageService languageService; + + @Inject + private GroupService groupService; + + @Inject + private MerchantStoreService merchantStoreService; + + @Inject + @Named("passwordEncoder") + private PasswordEncoder passwordEncoder; + + @Override + public User populate(PersistableUser source, User target, MerchantStore store, Language language) + throws ConversionException { + Validate.notNull(source, "PersistableUser cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + + if (target == null) { + target = new User(); + } + + target.setFirstName(source.getFirstName()); + target.setLastName(source.getLastName()); + target.setAdminEmail(source.getEmailAddress()); + target.setAdminName(source.getUserName()); + if(!StringUtils.isBlank(source.getPassword())) { + target.setAdminPassword(passwordEncoder.encode(source.getPassword())); + } + + if(!StringUtils.isBlank(source.getStore())) { + try { + MerchantStore userStore = merchantStoreService.getByCode(source.getStore()); + target.setMerchantStore(userStore); + } catch (ServiceException e) { + throw new ConversionException("Error while reading MerchantStore store [" + source.getStore() + "]",e); + } + } else { + target.setMerchantStore(store); + } + + + target.setActive(source.isActive()); + + Language lang = null; + try { + lang = languageService.getByCode(source.getDefaultLanguage()); + } catch(Exception e) { + throw new ConversionException("Cannot get language [" + source.getDefaultLanguage() + "]",e); + } + + // set default language + target.setDefaultLanguage(lang); + + List userGroups = new ArrayList(); + List names = new ArrayList(); + for (PersistableGroup group : source.getGroups()) { + names.add(group.getName()); + } + try { + List groups = groupService.listGroupByNames(names); + for(Group g: groups) { + userGroups.add(g); + } + } catch (Exception e1) { + throw new ConversionException("Error while getting user groups",e1); + } + + target.setGroups(userGroups); + + return target; + } + + @Override + protected User createTarget() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/populator/user/ReadableUserPopulator.java b/sm-shop/src/main/java/com/salesmanager/shop/populator/user/ReadableUserPopulator.java new file mode 100755 index 0000000000..23f9633e78 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/populator/user/ReadableUserPopulator.java @@ -0,0 +1,75 @@ +package com.salesmanager.shop.populator.user; + +import org.apache.commons.lang3.Validate; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.utils.AbstractDataPopulator; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.model.user.User; +import com.salesmanager.shop.model.security.ReadableGroup; +import com.salesmanager.shop.model.user.ReadableUser; +import com.salesmanager.shop.utils.DateUtil; + +/** + * Converts user model to readable user + * + * @author carlsamson + * + */ +public class ReadableUserPopulator extends AbstractDataPopulator { + + @Override + public ReadableUser populate(User source, ReadableUser target, MerchantStore store, + Language language) throws ConversionException { + Validate.notNull(source, "User cannot be null"); + + if (target == null) { + target = new ReadableUser(); + } + + target.setFirstName(source.getFirstName()); + target.setLastName(source.getLastName()); + target.setEmailAddress(source.getAdminEmail()); + target.setUserName(source.getAdminName()); + target.setActive(source.isActive()); + + if (source.getLastAccess() != null) { + target.setLastAccess(DateUtil.formatLongDate(source.getLastAccess())); + } + + // set default language + target.setDefaultLanguage(Constants.DEFAULT_LANGUAGE); + + if (source.getDefaultLanguage() != null) + target.setDefaultLanguage(source.getDefaultLanguage().getCode()); + target.setMerchant(store.getCode()); + target.setId(source.getId()); + + + for (Group group : source.getGroups()) { + + ReadableGroup g = new ReadableGroup(); + g.setName(group.getGroupName()); + g.setId(group.getId().longValue()); + target.getGroups().add(g); + } + + /** + * dates DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm a z"); + * myObjectMapper.setDateFormat(df); + */ + + + return target; + } + + @Override + protected ReadableUser createTarget() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/DefaultController.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/DefaultController.java new file mode 100644 index 0000000000..87a2c802ec --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/DefaultController.java @@ -0,0 +1,24 @@ +package com.salesmanager.shop.store.api; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; + + +@Controller +public class DefaultController { + + + @Autowired + private Environment env; + + @GetMapping(value = "/") + public @ResponseBody String version(Model model) { + + return "{\"version\":\""+ env.getProperty("application-version") +"\", \"build\":\"" + env.getProperty("build.timestamp") + "\"}"; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/ConstraintException.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/ConstraintException.java new file mode 100644 index 0000000000..3480787909 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/ConstraintException.java @@ -0,0 +1,23 @@ +package com.salesmanager.shop.store.api.exception; + +public class ConstraintException extends GenericRuntimeException { + + /** + * + */ + + + private static final long serialVersionUID = 1L; + + private static final String CONSTRAINT_ERROR_CODE = "506"; + + public ConstraintException(String message) { + super(CONSTRAINT_ERROR_CODE, message); + } + + public ConstraintException(String message, Throwable exception) { + super(CONSTRAINT_ERROR_CODE,message, exception); + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/ConversionRuntimeException.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/ConversionRuntimeException.java new file mode 100755 index 0000000000..9aa686c134 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/ConversionRuntimeException.java @@ -0,0 +1,29 @@ +package com.salesmanager.shop.store.api.exception; + +public class ConversionRuntimeException extends GenericRuntimeException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public ConversionRuntimeException(String errorCode, String message) { + super(errorCode, message); + } + + public ConversionRuntimeException(String message) { + super(message); + } + + public ConversionRuntimeException(Throwable exception) { + super(exception); + } + + public ConversionRuntimeException(String message, Throwable exception) { + super(message, exception); + } + + public ConversionRuntimeException(String errorCode, String message, Throwable exception) { + super(errorCode, message, exception); + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/ErrorEntity.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/ErrorEntity.java new file mode 100755 index 0000000000..4e08794a4f --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/ErrorEntity.java @@ -0,0 +1,18 @@ +package com.salesmanager.shop.store.api.exception; + +public class ErrorEntity { + private String errorCode; + private String message; + public String getErrorCode() { + return errorCode; + } + public void setErrorCode(String errorCode) { + this.errorCode = errorCode; + } + public String getMessage() { + return message; + } + public void setMessage(String message) { + this.message = message; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/FileUploadExceptionAdvice.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/FileUploadExceptionAdvice.java new file mode 100644 index 0000000000..743bf34701 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/FileUploadExceptionAdvice.java @@ -0,0 +1,32 @@ +package com.salesmanager.shop.store.api.exception; + +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.multipart.MaxUploadSizeExceededException; + +@ControllerAdvice +public class FileUploadExceptionAdvice { + + + private static final Logger log = LoggerFactory.getLogger(FileUploadExceptionAdvice.class); + + @ExceptionHandler(MaxUploadSizeExceededException.class) + @ResponseStatus(HttpStatus.PAYLOAD_TOO_LARGE) + public @ResponseBody ErrorEntity handleFileException(Exception exception) { + log.error(exception.getMessage(), exception); + ErrorEntity errorEntity = new ErrorEntity(); + + String resultMessage = exception.getLocalizedMessage() != null ? exception.getLocalizedMessage() : exception.getMessage(); + Optional.ofNullable(resultMessage) + .ifPresent(errorEntity::setMessage); + return errorEntity; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/GenericRuntimeException.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/GenericRuntimeException.java new file mode 100755 index 0000000000..f87cf9bbb1 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/GenericRuntimeException.java @@ -0,0 +1,55 @@ +package com.salesmanager.shop.store.api.exception; + + +public class GenericRuntimeException extends RuntimeException { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String errorCode; + private String errorMessage; + + public GenericRuntimeException(String errorCode, String errorMessage) { + this.setErrorCode(errorCode); + this.setErrorMessage(errorMessage); + } + + public GenericRuntimeException(String errorMessage) { + this.setErrorMessage(errorMessage); + } + + public GenericRuntimeException(Throwable exception) { + super(exception); + this.setErrorCode(null); + this.setErrorMessage(null); + } + + public GenericRuntimeException(String errorMessage, Throwable exception) { + super(exception); + this.setErrorCode(null); + this.setErrorMessage(errorMessage); + } + + public GenericRuntimeException(String errorCode, String errorMessage, Throwable exception) { + super(exception); + this.setErrorCode(errorCode); + this.setErrorMessage(errorMessage); + } + + public String getErrorCode() { + return errorCode; + } + + public void setErrorCode(String errorCode) { + this.errorCode = errorCode; + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/OperationNotAllowedException.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/OperationNotAllowedException.java new file mode 100755 index 0000000000..3395d45cb6 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/OperationNotAllowedException.java @@ -0,0 +1,17 @@ +package com.salesmanager.shop.store.api.exception; + +public class OperationNotAllowedException extends ServiceRuntimeException { + + private final static String ERROR_CODE = "304"; + + /** + * + */ + private static final long serialVersionUID = 1L; + + public OperationNotAllowedException(String message) { + super(ERROR_CODE, message); + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/ResourceNotFoundException.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/ResourceNotFoundException.java new file mode 100755 index 0000000000..b0abe73043 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/ResourceNotFoundException.java @@ -0,0 +1,20 @@ +package com.salesmanager.shop.store.api.exception; + +import org.apache.commons.lang3.StringUtils; + +public class ResourceNotFoundException extends ServiceRuntimeException { + + private final static String ERROR_CODE = "404"; + /** + * + */ + private static final long serialVersionUID = 1L; + + public ResourceNotFoundException(String errorCode, String message) { + super(StringUtils.isBlank(errorCode)? "404": errorCode, message); + } + + public ResourceNotFoundException(String message) { + super(ERROR_CODE, message); + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/RestApiException.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/RestApiException.java new file mode 100755 index 0000000000..706e321cf7 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/RestApiException.java @@ -0,0 +1,28 @@ +package com.salesmanager.shop.store.api.exception; + +public class RestApiException extends GenericRuntimeException { + /** + * + */ + private static final long serialVersionUID = 1L; + + public RestApiException(String errorCode, String message) { + super(errorCode, message); + } + + public RestApiException(String message) { + super(message); + } + + public RestApiException(Throwable exception) { + super(exception); + } + + public RestApiException(String message, Throwable exception) { + super(message, exception); + } + + public RestApiException(String errorCode, String message, Throwable exception) { + super(errorCode, message, exception); + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/RestErrorHandler.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/RestErrorHandler.java new file mode 100755 index 0000000000..054ea331d0 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/RestErrorHandler.java @@ -0,0 +1,113 @@ +package com.salesmanager.shop.store.api.exception; + +import java.util.Objects; +import java.util.Optional; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +@Order(Ordered.HIGHEST_PRECEDENCE) +@ControllerAdvice({"com.salesmanager.shop.store.api"}) +public class RestErrorHandler { + + private static final Logger log = LoggerFactory.getLogger(RestErrorHandler.class); + + @RequestMapping(produces = "application/json") + @ExceptionHandler(Exception.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public @ResponseBody ErrorEntity handleServiceException(Exception exception) { + log.error(exception.getMessage(), exception); + Objects.requireNonNull(exception.getCause()); + Throwable rootCause = exception.getCause(); + while (rootCause.getCause() != null && rootCause.getCause() != rootCause) { + rootCause = rootCause.getCause(); + } + ErrorEntity errorEntity = createErrorEntity("500", exception.getMessage(), + rootCause.getMessage()); + return errorEntity; + } + + + /** + * Generic exception serviceException handler + */ + @RequestMapping(produces = "application/json") + @ExceptionHandler(ServiceRuntimeException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public @ResponseBody ErrorEntity handleServiceException(ServiceRuntimeException exception) { + log.error(exception.getErrorMessage(), exception); + Throwable rootCause = exception.getCause(); + while (rootCause.getCause() != null && rootCause.getCause() != rootCause) { + rootCause = rootCause.getCause(); + } + ErrorEntity errorEntity = createErrorEntity(exception.getErrorCode()!=null?exception.getErrorCode():"500", exception.getErrorMessage(), + rootCause.getMessage()); + return errorEntity; + } + + @RequestMapping(produces = "application/json") + @ExceptionHandler(ConversionRuntimeException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public @ResponseBody ErrorEntity handleServiceException(ConversionRuntimeException exception) { + log.error(exception.getErrorMessage(), exception); + ErrorEntity errorEntity = createErrorEntity(exception.getErrorCode(), exception.getErrorMessage(), + exception.getLocalizedMessage()); + return errorEntity; + } + + @RequestMapping(produces = "application/json") + @ExceptionHandler(ResourceNotFoundException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public @ResponseBody ErrorEntity handleServiceException(ResourceNotFoundException exception) { + log.error(exception.getErrorMessage(), exception); + + ErrorEntity errorEntity = createErrorEntity(exception.getErrorCode(), exception.getErrorMessage(), + exception.getLocalizedMessage()); + return errorEntity; + } + + @RequestMapping(produces = "application/json") + @ExceptionHandler(UnauthorizedException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public @ResponseBody ErrorEntity handleServiceException(UnauthorizedException exception) { + log.error(exception.getErrorMessage(), exception); + + ErrorEntity errorEntity = createErrorEntity(exception.getErrorCode(), exception.getErrorMessage(), + exception.getLocalizedMessage()); + return errorEntity; + } + + @RequestMapping(produces = "application/json") + @ExceptionHandler(RestApiException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public @ResponseBody ErrorEntity handleRestApiException(RestApiException exception) { + log.error(exception.getErrorMessage(), exception); + + ErrorEntity errorEntity = createErrorEntity(exception.getErrorCode(), exception.getErrorMessage(), + exception.getLocalizedMessage()); + return errorEntity; + } + + private ErrorEntity createErrorEntity(String errorCode, String message, String detailMessage) { + ErrorEntity errorEntity = new ErrorEntity(); + Optional.ofNullable(errorCode) + .ifPresent(errorEntity::setErrorCode); + + String resultMessage = (message != null && detailMessage !=null) ? new StringBuilder().append(message).append(", ").append(detailMessage).toString() : detailMessage; + if(StringUtils.isBlank(resultMessage)) { + resultMessage = message; + } + Optional.ofNullable(resultMessage) + .ifPresent(errorEntity::setMessage); + return errorEntity; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/ServiceRuntimeException.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/ServiceRuntimeException.java new file mode 100755 index 0000000000..385c3a521d --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/ServiceRuntimeException.java @@ -0,0 +1,33 @@ +package com.salesmanager.shop.store.api.exception; + +import org.apache.commons.lang3.StringUtils; + +public class ServiceRuntimeException extends GenericRuntimeException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public ServiceRuntimeException(String errorCode, String message) { + super(errorCode, message); + } + + public ServiceRuntimeException(String message) { + super(message); + } + + public ServiceRuntimeException(Throwable exception) { + super(exception); + } + + public ServiceRuntimeException(String message, Throwable exception) { + super(message, exception); + } + + public ServiceRuntimeException(String errorCode, String message, Throwable exception) { + super(StringUtils.isBlank(errorCode)? "500": errorCode, message, exception); + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/UnauthorizedException.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/UnauthorizedException.java new file mode 100755 index 0000000000..58fd9dd6f6 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/exception/UnauthorizedException.java @@ -0,0 +1,20 @@ +package com.salesmanager.shop.store.api.exception; + +public class UnauthorizedException extends GenericRuntimeException { + + private final static String ERROR_CODE = "401"; + + private static final long serialVersionUID = 1L; + + public UnauthorizedException() { + super("Not authorized"); + } + + public UnauthorizedException(String errorCode, String message) { + super(errorCode, message); + } + + public UnauthorizedException(String message) { + super(ERROR_CODE, message); + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v0/store/StoreContactRESTController.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v0/store/StoreContactRESTController.java new file mode 100755 index 0000000000..880570e174 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v0/store/StoreContactRESTController.java @@ -0,0 +1,173 @@ +package com.salesmanager.shop.store.api.v0.store; + + +import java.util.Locale; +import java.util.Map; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +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.ResponseStatus; + +import com.salesmanager.core.business.services.catalog.category.CategoryService; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.merchant.MerchantStoreService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.utils.ajax.AjaxResponse; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.model.shop.ContactForm; +import com.salesmanager.shop.utils.EmailTemplatesUtils; +import com.salesmanager.shop.utils.LocaleUtils; + + +/** + * Rest services for sending contact + * @author Carl Samson + * + */ +@Controller +@RequestMapping("/services") +public class StoreContactRESTController { + + @Inject + private LanguageService languageService; + + @Inject + private MerchantStoreService merchantStoreService; + + @Inject + private EmailTemplatesUtils emailTemplatesUtils; + + + + private static final Logger LOGGER = LoggerFactory.getLogger(StoreContactRESTController.class); + + + + @RequestMapping( value="/public/{store}", method=RequestMethod.GET) + @ResponseStatus(HttpStatus.ACCEPTED) + @ResponseBody + public AjaxResponse store(@PathVariable final String store, HttpServletRequest request, HttpServletResponse response) { + + AjaxResponse ajaxResponse = new AjaxResponse(); + try { + + /** default routine **/ + + MerchantStore merchantStore = (MerchantStore)request.getAttribute(Constants.MERCHANT_STORE); + if(merchantStore!=null) { + if(!merchantStore.getCode().equals(store)) { + merchantStore = null; + } + } + + if(merchantStore== null) { + merchantStore = merchantStoreService.getByCode(store); + } + + if(merchantStore==null) { + LOGGER.error("Merchant store is null for code " + store); + response.sendError(503, "Merchant store is null for code " + store); + return null; + } + + Language language = merchantStore.getDefaultLanguage(); + + Map langs = languageService.getLanguagesMap(); + + + return null; + + + } catch (Exception e) { + LOGGER.error("Error while saving category",e); + try { + response.sendError(503, "Error while saving category " + e.getMessage()); + } catch (Exception ignore) { + } + return null; + } + } + + + @RequestMapping( value="/public/{store}/contact", method=RequestMethod.POST) + @ResponseStatus(HttpStatus.ACCEPTED) + @ResponseBody + public AjaxResponse contact(@PathVariable final String store, @Valid @RequestBody ContactForm contact, HttpServletRequest request, HttpServletResponse response) { + + AjaxResponse ajaxResponse = new AjaxResponse(); + try { + + /** default routine **/ + + MerchantStore merchantStore = (MerchantStore)request.getAttribute(Constants.MERCHANT_STORE); + if(merchantStore!=null) { + if(!merchantStore.getCode().equals(store)) { + merchantStore = null; + } + } + + if(merchantStore== null) { + merchantStore = merchantStoreService.getByCode(store); + } + + if(merchantStore==null) { + LOGGER.error("Merchant store is null for code " + store); + response.sendError(503, "Merchant store is null for code " + store); + return null; + } + + Language language = merchantStore.getDefaultLanguage(); + + Map langs = languageService.getLanguagesMap(); + + + if(!StringUtils.isBlank(request.getParameter(Constants.LANG))) { + String lang = request.getParameter(Constants.LANG); + if(lang!=null) { + language = langs.get(language); + } + } + + if(language==null) { + language = merchantStore.getDefaultLanguage(); + } + + Locale l = LocaleUtils.getLocale(language); + + + /** end default routine **/ + + + emailTemplatesUtils.sendContactEmail(contact, merchantStore, l, request.getContextPath()); + + ajaxResponse.setStatus(AjaxResponse.RESPONSE_STATUS_SUCCESS); + + return ajaxResponse; + + + } catch (Exception e) { + LOGGER.error("Error while saving category",e); + try { + response.sendError(503, "Error while saving category " + e.getMessage()); + } catch (Exception ignore) { + } + return null; + } + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v0/system/SystemRESTController.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v0/system/SystemRESTController.java new file mode 100755 index 0000000000..5ffc5cdc12 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v0/system/SystemRESTController.java @@ -0,0 +1,156 @@ +package com.salesmanager.shop.store.api.v0.system; + + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.core.MediaType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.salesmanager.core.business.services.system.ModuleConfigurationService; +import com.salesmanager.core.business.utils.ajax.AjaxResponse; + + +/** + * Rest services for the system configuration + * @author Carl Samson + * + */ +@Controller +@RequestMapping("/services") +public class SystemRESTController { + + + + private static final Logger LOGGER = LoggerFactory.getLogger(SystemRESTController.class); + + @Inject + private ModuleConfigurationService moduleConfigurationService; + + /** + * Creates or updates a configuration module. A JSON has to be created on the client side which represents + * an object that will create a new module (payment, shipping ...) which can be used and configured from + * the administration tool. Here is an example of configuration accepted + * + * { + "module": "PAYMENT", + "code": "paypal-express-checkout", + "type":"paypal", + "version":"104.0", + "regions": ["*"], + "image":"icon-paypal.png", + "configuration":[{"env":"TEST","scheme":"","host":"","port":"","uri":"","config1":"https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token="},{"env":"PROD","scheme":"","host":"","port":"","uri":"","config1":"https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token="}] + + } + * + * see : shopizer/sm-core/src/main/resources/reference/integrationmodules.json for more samples + * @param json + * @param request + * @param response + * @throws Exception + */ + @RequestMapping( value="/private/system/module", method=RequestMethod.POST, consumes = "text/plain;charset=UTF-8") + @ResponseBody + public AjaxResponse createOrUpdateModule(@RequestBody final String json, HttpServletRequest request, HttpServletResponse response) throws Exception { + + + AjaxResponse resp = new AjaxResponse(); + + try { + + + + LOGGER.debug("Creating or updating an integration module : " + json); + + moduleConfigurationService.createOrUpdateModule(json); + + response.setStatus(200); + + resp.setStatus(200); + + } catch(Exception e) { + resp.setStatus(500); + resp.setErrorMessage(e); + response.sendError(503, "Exception while creating or updating the module " + e.getMessage()); + } + + return resp; + + } + + @RequestMapping( value="/private/system/optin", method=RequestMethod.POST) + @ResponseBody + public AjaxResponse createOptin(@RequestBody final String json, HttpServletRequest request, HttpServletResponse response) throws Exception { + + + AjaxResponse resp = new AjaxResponse(); + + try { + LOGGER.debug("Creating an optin : " + json); + //moduleConfigurationService.createOrUpdateModule(json); + response.setStatus(200); + resp.setStatus(200); + + } catch(Exception e) { + resp.setStatus(500); + resp.setErrorMessage(e); + response.sendError(503, "Exception while creating optin " + e.getMessage()); + } + + return resp; + + } + + @RequestMapping( value="/private/system/optin/{code}", method=RequestMethod.DELETE) + @ResponseBody + public AjaxResponse deleteOptin(@RequestBody final String code, HttpServletRequest request, HttpServletResponse response) throws Exception { + + + AjaxResponse resp = new AjaxResponse(); + + try { + LOGGER.debug("Delete optin : " + code); + //moduleConfigurationService.createOrUpdateModule(json); + response.setStatus(200); + resp.setStatus(200); + + } catch(Exception e) { + resp.setStatus(500); + resp.setErrorMessage(e); + response.sendError(503, "Exception while deleting optin " + e.getMessage()); + } + + return resp; + + } + + @RequestMapping( value="/private/system/optin/{code}/customer", method=RequestMethod.POST, consumes = "application/json") + @ResponseBody + public AjaxResponse createOptinCustomer(@RequestBody final String code, HttpServletRequest request, HttpServletResponse response) throws Exception { + + + AjaxResponse resp = new AjaxResponse(); + + try { + LOGGER.debug("Adding a customer optin : " + code); + //moduleConfigurationService.createOrUpdateModule(json); + response.setStatus(200); + resp.setStatus(200); + + } catch(Exception e) { + resp.setStatus(500); + resp.setErrorMessage(e); + response.sendError(503, "Exception while creating uptin " + e.getMessage()); + } + + return resp; + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/catalog/CatalogApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/catalog/CatalogApi.java new file mode 100644 index 0000000000..1b9ebbef29 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/catalog/CatalogApi.java @@ -0,0 +1,214 @@ +package com.salesmanager.shop.store.api.v1.catalog; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.catalog.PersistableCatalog; +import com.salesmanager.shop.model.catalog.catalog.PersistableCatalogCategoryEntry; +import com.salesmanager.shop.model.catalog.catalog.ReadableCatalog; +import com.salesmanager.shop.model.catalog.catalog.ReadableCatalogCategoryEntry; +import com.salesmanager.shop.model.entity.EntityExists; +import com.salesmanager.shop.model.entity.ReadableEntityList; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.controller.catalog.facade.CatalogFacade; +import io.swagger.annotations.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.Optional; + +@RestController +@RequestMapping(value = "/api/v1") +@Api(tags = {"Catalog management resource (Catalog Management Api)"}) +@SwaggerDefinition(tags = { + @Tag(name = "Catalog management resource", description = "Manage catalogs and attached products") +}) +public class CatalogApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(CatalogApi.class); + + @Autowired + private CatalogFacade catalogFacade; + + + @GetMapping(value = "/private/catalogs") + @ResponseStatus(HttpStatus.OK) + @ApiOperation(httpMethod = "GET", value = "Get catalogs by merchant", notes = "", + response = ReadableEntityList.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en")}) + public ReadableEntityList getCatalogs( + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, + Optional code, + @RequestParam(value = "page", required = false, defaultValue="0") Integer page, + @RequestParam(value = "count", required = false, defaultValue="10") Integer count) { + + return catalogFacade.getListCatalogs(code, merchantStore, language, page, count); + + } + + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = {"/private/catalog/unique"}, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") + }) + @ApiOperation(httpMethod = "GET", value = "Check if catalog code already exists", notes = "", + response = EntityExists.class) + public ResponseEntity exists( + @RequestParam(value = "code") String code, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + boolean existByCode = catalogFacade.uniqueCatalog(code, merchantStore); + return new ResponseEntity(new EntityExists(existByCode), HttpStatus.OK); + } + + + @PostMapping(value = "/private/catalog") + @ResponseStatus(HttpStatus.OK) + @ApiOperation(httpMethod = "POST", value = "Create catalog", notes = "", + response = Void.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en")}) + public ReadableCatalog createCatalog( + @RequestBody @Valid PersistableCatalog catalog, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + return catalogFacade.saveCatalog(catalog, merchantStore, language); + + } + + @PatchMapping(value = "/private/catalog/{id}") + @ResponseStatus(HttpStatus.OK) + @ApiOperation(httpMethod = "PATCH", value = "Update catalog", notes = "", + response = Void.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en")}) + public void updateCatalog( + @PathVariable Long id, + @RequestBody @Valid PersistableCatalog catalog, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + catalog.setId(id); + catalogFacade.updateCatalog(id, catalog, merchantStore, language); + + } + + @GetMapping(value = "/private/catalog/{id}") + @ResponseStatus(HttpStatus.OK) + @ApiOperation(httpMethod = "GET", value = "Get catalog", notes = "", + response = Void.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en")}) + public ReadableCatalog getCatalog( + @PathVariable Long id, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + return catalogFacade.getCatalog(id, merchantStore, language); + + } + + + + @DeleteMapping(value = "/private/catalog/{id}") + @ApiOperation(httpMethod = "DELETE", value = "Deletes a catalog", notes = "", + response = Void.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en")}) + public void deleteCatalog( + @PathVariable Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + catalogFacade.deleteCatalog(id, merchantStore, language); + } + + @PostMapping(value = "/private/catalog/{id}") + @ResponseStatus(HttpStatus.OK) + @ApiOperation(httpMethod = "POST", value = "Add catalog entry to catalog", notes = "", + response = ReadableCatalogCategoryEntry.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en")}) + public ReadableCatalogCategoryEntry addCatalogEntry( + @PathVariable Long id, + @RequestBody @Valid PersistableCatalogCategoryEntry catalogEntry, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + + + ReadableCatalog c = catalogFacade.getCatalog(id, merchantStore, language); + + if(c == null) { + throw new ResourceNotFoundException("Catalog id [" + id + "] not found"); + } + + catalogEntry.setCatalog(c.getCode()); + return catalogFacade.addCatalogEntry(catalogEntry, merchantStore, language); + + + } + + @DeleteMapping(value = "/private/catalog/{id}/entry/{entryId}") + @ResponseStatus(HttpStatus.OK) + @ApiOperation(httpMethod = "DELETE", value = "Remove catalog entry from catalog", notes = "", + response = Void.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en")}) + public void removeCatalogEntry( + @PathVariable Long id, + @PathVariable Long entryId, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + + catalogFacade.removeCatalogEntry(id, entryId, merchantStore, language); + + + + } + + @GetMapping(value = "/private/catalog/{id}/entry") + @ResponseStatus(HttpStatus.OK) + @ApiOperation(httpMethod = "GET", value = "Get catalog entry by catalog", notes = "", + response = ReadableEntityList.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en")}) + public ReadableEntityList getCatalogEntry( + @PathVariable(value="id") Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + @RequestParam(value = "page", required = false, defaultValue="0") Integer page, + @RequestParam(value = "count", required = false, defaultValue="10") Integer count, + HttpServletRequest request) { + + return catalogFacade.listCatalogEntry(catalogEntryFilter(request), id, merchantStore, language, page, count); + + + } + + private Optional catalogFilter(HttpServletRequest request) { + + return Optional.ofNullable((String)request.getAttribute("code")); + } + + private Optional catalogEntryFilter(HttpServletRequest request) { + + return Optional.ofNullable((String)request.getAttribute("name")); +} + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/category/CategoryApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/category/CategoryApi.java new file mode 100755 index 0000000000..2dd4bfe046 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/category/CategoryApi.java @@ -0,0 +1,238 @@ +package com.salesmanager.shop.store.api.v1.category; + +import static org.springframework.http.HttpStatus.OK; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.inject.Inject; +import javax.validation.Valid; + +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.model.catalog.category.PersistableCategory; +import com.salesmanager.shop.model.catalog.category.ReadableCategory; +import com.salesmanager.shop.model.catalog.category.ReadableCategoryList; +import com.salesmanager.shop.model.entity.EntityExists; +import com.salesmanager.shop.model.entity.ListCriteria; +import com.salesmanager.shop.store.api.exception.UnauthorizedException; +import com.salesmanager.shop.store.controller.category.facade.CategoryFacade; +import com.salesmanager.shop.store.controller.user.facade.UserFacade; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@RestController +@RequestMapping(value = "/api/v1") +@Api(tags = { "Category management resource (Category Management Api)" }) +@SwaggerDefinition(tags = { + @Tag(name = "Category management resource", description = "Manage category and attached products") }) +public class CategoryApi { + + private static final int DEFAULT_CATEGORY_DEPTH = 0; + + @Inject + private CategoryFacade categoryFacade; + + @Inject + private UserFacade userFacade; + + @GetMapping(value = "/category/{id}", produces = { APPLICATION_JSON_VALUE }) + @ApiOperation(httpMethod = "GET", value = "Get category list for an given Category id", notes = "List current Category and child category") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "List of category found", response = ReadableCategory.class) }) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public ReadableCategory get( + @PathVariable(name = "id") Long categoryId, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + ReadableCategory category = categoryFacade.getById(merchantStore, categoryId, language); + return category; + } + + @GetMapping(value = "/category/name/{friendlyUrl}", produces = { APPLICATION_JSON_VALUE }) + @ApiOperation(httpMethod = "GET", value = "Get category list for an given Category code", notes = "List current Category and child category") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "List of category found", response = ReadableCategory.class) }) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") + }) + public ReadableCategory getByfriendlyUrl( + @PathVariable(name = "friendlyUrl") String friendlyUrl, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) throws Exception { + ReadableCategory category = categoryFacade.getCategoryByFriendlyUrl(merchantStore, friendlyUrl, language); + return category; + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/category/unique" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + @ApiOperation(httpMethod = "GET", value = "Check if category code already exists", notes = "", response = EntityExists.class) + public ResponseEntity exists(@RequestParam(value = "code") String code, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + boolean isCategoryExist = categoryFacade.existByCode(merchantStore, code); + return new ResponseEntity(new EntityExists(isCategoryExist), HttpStatus.OK); + } + + /** + * Get all category starting from root filter can be used for filtering on + * fields only featured is supported + * + * @return + */ + @GetMapping(value = "/category", produces = { APPLICATION_JSON_VALUE }) + @ApiOperation(httpMethod = "GET", value = "Get category hierarchy from root. Supports filtering FEATURED_CATEGORIES and VISIBLE ONLY by adding ?filter=[featured] or ?filter=[visible] or ? filter=[featured,visible", notes = "Does not return any product attached") + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public ReadableCategoryList list( + @RequestParam(value = "filter", required = false) List filter, + @RequestParam(value = "name", required = false) String name, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, + @RequestParam(value = "count", required = false, defaultValue = "10") Integer count) { + + + ListCriteria criteria = new ListCriteria(); + criteria.setName(name); + return categoryFacade.getCategoryHierarchy(merchantStore, criteria, DEFAULT_CATEGORY_DEPTH, language, filter, + page, count); + } + + + @GetMapping(value = "/category/product/{ProductId}", produces = { APPLICATION_JSON_VALUE }) + @ApiOperation(httpMethod = "GET", value = "Get category by product", notes = "") + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public ReadableCategoryList list( + @PathVariable(name = "ProductId") Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language lang) { + + + return categoryFacade.listByProduct(merchantStore, id, lang); + + } + + @ResponseStatus(HttpStatus.CREATED) + @PostMapping(value = "/private/category", produces = { APPLICATION_JSON_VALUE }) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public PersistableCategory create( + @Valid @RequestBody PersistableCategory category, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + // superadmin, admin and admin_catalogue + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + return categoryFacade.saveCategory(merchantStore, category); + } + + @PutMapping(value = "/private/category/{id}", produces = { APPLICATION_JSON_VALUE }) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public PersistableCategory update(@PathVariable Long id, @Valid @RequestBody PersistableCategory category, + @ApiIgnore MerchantStore merchantStore) { + + // superadmin, admin and admin_catalogue + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + + category.setId(id); + return categoryFacade.saveCategory(merchantStore, category); + } + + @PatchMapping(value = "/private/category/{id}/visible", produces = { APPLICATION_JSON_VALUE }) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public void updateVisible(@PathVariable Long id, @Valid @RequestBody PersistableCategory category, + @ApiIgnore MerchantStore merchantStore + ) { + + // superadmin, admin and admin_catalogue + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + category.setId(id); + categoryFacade.setVisible(category, merchantStore); + } + + @PutMapping(value = "/private/category/{id}/move/{parent}", produces = { APPLICATION_JSON_VALUE }) + @ApiOperation(httpMethod = "PUT", value = "Move a category under another category", notes = "Move category {id} under category {parent}") + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public void move( + @PathVariable Long id, + @PathVariable Long parent, + @ApiIgnore MerchantStore merchantStore) { + // superadmin, admin and admin_catalogue + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + + categoryFacade.move(id, parent, merchantStore); + return; + } + + @DeleteMapping(value = "/private/category/{id}", produces = { APPLICATION_JSON_VALUE }) + @ResponseStatus(OK) + public void delete(@PathVariable("id") Long categoryId, @ApiIgnore MerchantStore merchantStore) { + + // superadmin, admin and admin_catalogue + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + + categoryFacade.deleteCategory(categoryId, merchantStore); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/configurations/CacheApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/configurations/CacheApi.java new file mode 100755 index 0000000000..d3c1676049 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/configurations/CacheApi.java @@ -0,0 +1,58 @@ +package com.salesmanager.shop.store.api.v1.configurations; + +import javax.inject.Inject; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; +import com.salesmanager.core.business.utils.CacheUtils; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.store.facade.StoreFacade; + +/** + * + */ + +@RestController +@RequestMapping(value = "/api/v1") +public class CacheApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(CacheApi.class); + + @Inject + private StoreFacade storeFacade; + + @Inject + private CacheUtils cache; + + @DeleteMapping(value = "/auth/cache/store/{storeId}/clear") + public @ResponseBody ResponseEntity clearCache(@PathVariable("storeId") String storeCode, + @RequestParam(name = "cacheKey", required = false) String cacheKey) { + + try { + MerchantStore merchantStore = storeFacade.get(storeCode); + StringBuilder key = + new StringBuilder().append(merchantStore.getId()).append("_").append(cacheKey); + + if (StringUtils.isNotEmpty(cacheKey)) { + cache.removeFromCache(key.toString()); + } else { + cache.removeAllFromCache(merchantStore); + } + } catch (Exception e) { + LOGGER.error("Error while clearning cache {}", e.getCause()); + throw new ServiceRuntimeException("Error while clearing cache"); + } + + return new ResponseEntity<>(HttpStatus.OK); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/configurations/ConfigurationsApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/configurations/ConfigurationsApi.java new file mode 100644 index 0000000000..60e43c3d41 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/configurations/ConfigurationsApi.java @@ -0,0 +1,96 @@ +package com.salesmanager.shop.store.api.v1.configurations; + +import java.util.List; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.configuration.ReadableConfiguration; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@RestController +@RequestMapping(value = "/api/v1") +@Api(tags = { "Configurations management" }) +@SwaggerDefinition(tags = { + @Tag(name = "Configurations management", description = "Configurations management for modules") }) +public class ConfigurationsApi { + + + /** Configurations of modules */ + @PostMapping("/private/configurations/payment") + @ApiOperation( + httpMethod = "POST", + value = "Manages payment configurations", + notes = "Requires administration access", + produces = "application/json", + response = Void.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") + }) + public Void create( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + //return customerFacade.create(customer, merchantStore, language); + return null; + + } + + + /** Configurations of payment modules */ + @GetMapping("/private/configurations/payment") + @ApiOperation( + httpMethod = "GET", + value = "List payment configurations summary", + notes = "Requires administration access", + produces = "application/json", + response = List.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") + }) + public List listPaymentConfigurations( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + //return customerFacade.create(customer, merchantStore, language); + return null; + + } + + + + + /** Configurations of shipping modules */ + @GetMapping("/private/configurations/shipping") + @ApiOperation( + httpMethod = "GET", + value = "List shipping configurations summary", + notes = "Requires administration access", + produces = "application/json", + response = List.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") + }) + public List listShippingConfigurations( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + //return customerFacade.create(customer, merchantStore, language); + return null; + + } + + + + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/content/ContentAdministrationApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/content/ContentAdministrationApi.java new file mode 100644 index 0000000000..12aa062baa --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/content/ContentAdministrationApi.java @@ -0,0 +1,363 @@ +package com.salesmanager.shop.store.api.v1.content; + +import java.io.IOException; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.content.Content; +import com.salesmanager.shop.model.content.ContentFile; +import com.salesmanager.shop.model.content.ContentFolder; +import com.salesmanager.shop.store.api.exception.RestApiException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.content.facade.ContentFacade; +import com.salesmanager.shop.utils.FileNameUtils; +import com.salesmanager.shop.utils.ImageFilePath; + +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import springfox.documentation.annotations.ApiIgnore; + +/** + * Administration tool dedicated api + * @author carlsamson + * + */ +@RestController +@RequestMapping(value = "/api/v1") +@CrossOrigin(origins = "*", maxAge = 3600) +public class ContentAdministrationApi { + + + private static final String DEFAULT_PATH = "/"; + + private static final Logger LOGGER = LoggerFactory.getLogger(ContentAdministrationApi.class); + + @Inject + private ContentFacade contentFacade; + + @Autowired + private FileNameUtils fileNameUtils; + + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + /** + * Works with ng-file-man client + * + * @param path + * @param merchantStore + * @param language + * @return + * @throws Exception + */ + @GetMapping(value = "/private/content/list", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public List list(@RequestParam(value = "parentPath", required = false) String path, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) throws Exception { + + String decodedPath = decodeContentPath(path); + + ContentFolder folder = contentFacade.getContentFolder(decodedPath, merchantStore); + List files = folder.getContent().stream().map(x -> convertToImageFile(merchantStore, x)) + .collect(Collectors.toList()); + + return files; + } + + /** + * @param path + * @param merchantStore + * @param language + * @return + * @throws Exception + */ + @GetMapping(value = "/private/content/folder", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ContentFolder folder( + @RequestParam(value = "path", required = false) String path, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) throws Exception { + String decodedPath = decodeContentPath(path); + return contentFacade.getContentFolder(decodedPath, merchantStore); + } + + + /** + * works with file manager (javascript client) + * @param files + * @param merchantStore + * @param language + */ + @PostMapping(value = "/private/content/images/add", consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }) + @ResponseStatus(HttpStatus.CREATED) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public FileStatus upload( + @RequestParam(value = "qqfile", required = true) MultipartFile qqfile, + @RequestParam(value = "qquuid", required = true) String qquuid, + @RequestParam(value = "qqfilename", required = true) String qqfilename, + @RequestParam(value = "qqtotalfilesize", required = false) Long qqtotalfilesize, + @RequestParam(value = "parentPath", required = false) String parentPath, + @RequestParam(value = "qqpartindex", required = false) Integer qqpartindex, + @RequestParam(value = "qqtotalparts", required = false) Integer qqtotalparts, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + if(!fileNameUtils.validFileName(qqfilename)) { + FileStatus fs = new FileStatus(); + fs.setError("Invalid filename"); + fs.setSuccess(false); + return fs; + } + + ContentFile cf = new ContentFile(); + cf.setContentType(qqfile.getContentType()); + cf.setName(qqfilename); + try { + cf.setFile(qqfile.getBytes()); + contentFacade.addContentFile(cf, merchantStore.getCode()); + return new FileStatus(); + } catch (IOException e) { + //throw new ServiceRuntimeException("Error while getting file bytes"); + LOGGER.error("Error when uploadging file",e); + FileStatus fs = new FileStatus(); + fs.setError(e.getMessage()); + fs.setSuccess(false); + return fs; + } + + } + + @GetMapping(value = "/content/images/download") + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody String download( + @RequestParam(value = "path", required = true) String path, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + String fileName = path.substring(path.lastIndexOf("/")+1, path.length()); + try { + + //OutputContentFile file = contentFacade.download(merchantStore, FileContentType.IMAGE, fileName); + //return file.getFile().toByteArray(); + //return "https://s3.ca-central-1.amazonaws.com/shopizer-carl/files/DEFAULT/85.jpg"; + return null; + } catch (Exception e) { + //throw new ServiceRuntimeException("Error while getting file bytes"); + LOGGER.error("Error when renaming file",e); + throw new ServiceRuntimeException("Error while downloading file [" + fileName + "]"); + } + + } + + @PostMapping(value = "/private/content/images/rename", produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseStatus(HttpStatus.OK) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public FileStatus rename( + @RequestParam(value = "path", required = true) String path, + @RequestParam(value = "newName", required = true) String newName, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + try { + + String fileName = path.substring(path.lastIndexOf("/")+1, path.length()); + contentFacade.renameFile(merchantStore, FileContentType.IMAGE, fileName, newName); + return new FileStatus(); + } catch (Exception e) { + //throw new ServiceRuntimeException("Error while getting file bytes"); + LOGGER.error("Error when renaming file",e); + FileStatus fs = new FileStatus(); + fs.setError(e.getMessage()); + fs.setSuccess(false); + return fs; + } + + } + + @DeleteMapping(value = "/private/content/images/remove", produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseStatus(HttpStatus.OK) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public FileStatus remove( + @RequestParam(value = "path", required = true) String path, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + try { + + String fileName = path.substring(path.lastIndexOf("/")+1, path.length()); + contentFacade.delete(merchantStore, fileName, FileContentType.IMAGE.name()); + return new FileStatus(); + } catch (Exception e) { + //throw new ServiceRuntimeException("Error while getting file bytes"); + LOGGER.error("Error when renaming file",e); + FileStatus fs = new FileStatus(); + fs.setError(e.getMessage()); + fs.setSuccess(false); + return fs; + } + + } + + + private ImageFile convertToImageFile(MerchantStore store, Content content) { + ImageFile f = new ImageFile(); + f.setDir(false); + f.setId(imageUtils.buildStaticImageUtils(store, content.getName())); + f.setName(content.getName()); + f.setUrl(imageUtils.buildStaticImageUtils(store, content.getName())); + f.setPath("image.png"); + f.setSize(null); + return f; + } + + private ImageFile convertToFolder(String folder) { + ImageFile f = new ImageFile(); + f.setDir(true); + f.setId(UUID.randomUUID().toString()); + f.setName(DEFAULT_PATH + "images"); + f.setUrl(DEFAULT_PATH + "images"); + f.setPath(DEFAULT_PATH + "images"); + return f; + } + + private String decodeContentPath(String path) throws UnsupportedEncodingException { + try { + return StringUtils.isBlank(path) || path.contains("/images") ? "/" : URLDecoder.decode(path.replaceAll(",",""), "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RestApiException(e); + } + + } + + class FileStatus implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private boolean success = true; + private String error = null; + private boolean preventRetry = true; + public boolean isSuccess() { + return success; + } + public void setSuccess(boolean success) { + this.success = success; + } + public String getError() { + return error; + } + public void setError(String error) { + this.error = error; + } + public boolean isPreventRetry() { + return preventRetry; + } + public void setPreventRetry(boolean preventRetry) { + this.preventRetry = preventRetry; + } + + } + + + class ImageFile implements Serializable { + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSize() { + return size; + } + + public void setSize(String size) { + this.size = size; + } + + public boolean isDir() { + return dir; + } + + public void setDir(boolean dir) { + this.dir = dir; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + /** + * + */ + private static final long serialVersionUID = 1L; + private String url; + private String name; + private String size; + private boolean dir; + private String path; + private String id; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/content/ContentApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/content/ContentApi.java new file mode 100755 index 0000000000..f0c6a319fc --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/content/ContentApi.java @@ -0,0 +1,520 @@ +package com.salesmanager.shop.store.api.v1.content; + +import java.io.IOException; +import java.util.List; +import java.util.Optional; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import com.salesmanager.core.model.content.ContentType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.content.ContentFile; +import com.salesmanager.shop.model.content.ContentFolder; +import com.salesmanager.shop.model.content.ContentName; +import com.salesmanager.shop.model.content.PersistableContentEntity; +import com.salesmanager.shop.model.content.ReadableContentEntity; +import com.salesmanager.shop.model.content.ReadableContentFull; +import com.salesmanager.shop.model.content.box.PersistableContentBox; +import com.salesmanager.shop.model.content.box.ReadableContentBox; +import com.salesmanager.shop.model.content.page.PersistableContentPage; +import com.salesmanager.shop.model.content.page.ReadableContentPage; +import com.salesmanager.shop.model.entity.Entity; +import com.salesmanager.shop.model.entity.EntityExists; +import com.salesmanager.shop.model.entity.ReadableEntityList; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.content.facade.ContentFacade; +import com.salesmanager.shop.utils.ImageFilePath; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@RestController +@RequestMapping(value = "/api/v1") +@Api(tags = { "Content management resource (Content Management Api)" }) +@SwaggerDefinition(tags = { + @Tag(name = "Content management resource", description = "Add pages, content boxes, manage images and files") }) +public class ContentApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(ContentApi.class); + + private static final String DEFAULT_PATH = "/"; + + private final static String BOX = "BOX"; + private final static String PAGE = "PAGE"; + + @Inject + private ContentFacade contentFacade; + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + /** + * List content pages + * @param merchantStore + * @param language + * @param page + * @param count + * @return + */ + @GetMapping(value = {"/private/content/pages", "/content/pages"}, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get page names created for a given MerchantStore", notes = "", produces = "application/json", response = List.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableEntityList pages( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + int page, + int count) { + return contentFacade + .getContentPages(merchantStore, language, page, count); + } + + @Deprecated + @GetMapping(value = "/content/summary", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get pages summary created for a given MerchantStore. Content summary is a content bux having code summary.", notes = "", produces = "application/json", response = List.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public List pagesSummary( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + //return contentFacade.getContentBoxes(ContentType.BOX, "summary_", merchantStore, language); + return null; + } + + /** + * List all boxes + * + * @param merchantStore + * @param language + * @return + */ + @GetMapping(value = {"/content/boxes","/private/content/boxes"}, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get boxes for a given MerchantStore", notes = "", produces = "application/json", response = List.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableEntityList boxes( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + int page, + int count + ) { + return contentFacade.getContentBoxes(ContentType.BOX, merchantStore, language, page, count); + } + + /** + * List specific content box + * @param code + * @param merchantStore + * @param language + * @return + */ + @GetMapping(value = "/content/pages/{code}", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get page content by code for a given MerchantStore", notes = "", produces = "application/json", response = ReadableContentPage.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableContentPage page(@PathVariable("code") String code, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + return contentFacade.getContentPage(code, merchantStore, language); + + } + + /** + * Get content page by name + * @param name + * @param merchantStore + * @param language + * @return + */ + @GetMapping(value = "/content/pages/name/{name}", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get page content by code for a given MerchantStore", notes = "", produces = "application/json", response = ReadableContentPage.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableContentPage pageByName(@PathVariable("name") String name, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + return contentFacade.getContentPageByName(name, merchantStore, language); + + } + + /** + * Create content box + * + * @param page + * @param merchantStore + * @param language + * @param pageCode + */ + @PostMapping(value = "/private/content/box") + @ResponseStatus(HttpStatus.CREATED) + @ApiOperation(httpMethod = "POST", value = "Create content box", notes = "", response = Entity.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public Entity createBox( + @RequestBody @Valid PersistableContentBox box, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + Long id = contentFacade.saveContentBox(box, merchantStore, language); + Entity entity = new Entity(); + entity.setId(id); + return entity; + } + + @GetMapping(value = "/private/content/box/{code}/exists") + @ResponseStatus(HttpStatus.OK) + @ApiOperation(httpMethod = "GET", value = "Check unique content box", notes = "", response = EntityExists.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public EntityExists boxExists( + @PathVariable String code, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + boolean exists = contentFacade.codeExist(code, BOX, merchantStore); + EntityExists entity = new EntityExists(exists); + return entity; + } + + @GetMapping(value = "/private/content/page/{code}/exists") + @ResponseStatus(HttpStatus.OK) + @ApiOperation(httpMethod = "GET", value = "Check unique content page", notes = "", response = EntityExists.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public EntityExists pageExists( + @PathVariable String code, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + boolean exists = contentFacade.codeExist(code, PAGE, merchantStore); + EntityExists entity = new EntityExists(exists); + return entity; + } + + /** + * Create content page + * @param page + * @param merchantStore + * @param language + */ + @PostMapping(value = "/private/content/page") + @ResponseStatus(HttpStatus.CREATED) + @ApiOperation(httpMethod = "POST", value = "Create content page", notes = "", response = Entity.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public Entity createPage( + @RequestBody @Valid PersistableContentPage page, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + Long id = contentFacade.saveContentPage(page, merchantStore, language); + Entity entity = new Entity(); + entity.setId(id); + return entity; + } + + + /** + * Delete content page + * @param id + * @param merchantStore + * @param language + */ + @DeleteMapping(value = "/private/content/page/{id}") + @ResponseStatus(HttpStatus.OK) + @ApiOperation(httpMethod = "DELETE", value = "Delete content page", notes = "", response = Void.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void deletePage( + @PathVariable Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + contentFacade.delete(merchantStore, id); + + } + + /** + * Delete content box + * @param id + * @param merchantStore + * @param language + */ + @DeleteMapping(value = "/private/content/box/{id}") + @ResponseStatus(HttpStatus.OK) + @ApiOperation(httpMethod = "DELETE", value = "Delete content box", notes = "", response = Void.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void deleteBox( + @PathVariable Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + contentFacade.delete(merchantStore, id); + + } + + @PutMapping(value = "/private/content/page/{id}") + @ResponseStatus(HttpStatus.OK) + @ApiOperation(httpMethod = "PUT", value = "Update content page", notes = "", response = Void.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void updatePage( + @RequestBody @Valid PersistableContentPage page, + @PathVariable Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + contentFacade.updateContentPage(id, page, merchantStore, language); + } + + @PutMapping(value = "/private/content/box/{id}") + @ResponseStatus(HttpStatus.OK) + @ApiOperation(httpMethod = "PUT", value = "Update content box", notes = "", response = Void.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void updateBox( + @RequestBody @Valid PersistableContentBox box, + @PathVariable Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + contentFacade.updateContentBox(id, box, merchantStore, language); + } + + @Deprecated + @GetMapping(value = "/private/content/any/{code}", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get page content by code for a given MerchantStore", notes = "", produces = "application/json", response = ReadableContentPage.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableContentFull content(@PathVariable("code") String code, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + return contentFacade.getContent(code, merchantStore, language); + + } + + @Deprecated + @GetMapping(value = "/private/contents/any", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get contents (page and box) for a given MerchantStore", notes = "", produces = "application/json", response = ReadableContentPage.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public List contents(@ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + Optional op = Optional.empty(); + return contentFacade.getContents(op, merchantStore, language); + + } + + + @GetMapping(value = "/private/content/boxes/{code}", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Manage box content by code for a code and a given MerchantStore", notes = "", produces = "application/json", response = List.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableContentBox manageBoxByCode(@PathVariable("code") String code, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + return contentFacade.getContentBox(code, merchantStore, language); + } + + @GetMapping(value = "/content/boxes/{code}", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get box content by code for a code and a given MerchantStore", notes = "", produces = "application/json", response = List.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableContentBox getBoxByCode(@PathVariable("code") String code, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + return contentFacade.getContentBox(code, merchantStore, language); + } + + + + + + /** + * + * @param parent + * @param folder + * @param merchantStore + * @param language + */ + @DeleteMapping(value = "/content/folder", produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseStatus(HttpStatus.CREATED) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void addFolder(@RequestParam String parent, @RequestParam String folder, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + } + + /** + * @param code + * @param path + * @param request + * @param response + * @return + * @throws Exception + */ + @GetMapping(value = "/content/images", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get store content images", notes = "", response = ContentFolder.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ContentFolder images(@ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, + @RequestParam(value = "path", required = false) String path, HttpServletRequest request, + HttpServletResponse response) throws Exception { + + //String decodedPath = decodeContentPath(path); + ContentFolder folder = contentFacade.getContentFolder(path, merchantStore); + return folder; + } + + + + /** + * Need type, name and entity + * + * @param file + */ + @PostMapping(value = "/private/file") + @ResponseStatus(HttpStatus.CREATED) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void upload(@RequestParam("file") MultipartFile file, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + ContentFile f = new ContentFile(); + f.setContentType(file.getContentType()); + f.setName(file.getOriginalFilename()); + try { + f.setFile(file.getBytes()); + } catch (IOException e) { + throw new ServiceRuntimeException("Error while getting file bytes"); + } + + contentFacade.addContentFile(f, merchantStore.getCode()); + + } + + @PostMapping(value = "/private/files", consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }) + @ResponseStatus(HttpStatus.CREATED) + @ApiImplicitParams({ + // @ApiImplicitParam(name = "file[]", value = "File stream object", + // required = true,dataType = "MultipartFile",allowMultiple = true), + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void uploadMultipleFiles(@RequestParam(value = "file[]", required = true) MultipartFile[] files, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + for (MultipartFile f : files) { + ContentFile cf = new ContentFile(); + cf.setContentType(f.getContentType()); + cf.setName(f.getName()); + try { + cf.setFile(f.getBytes()); + contentFacade.addContentFile(cf, merchantStore.getCode()); + } catch (IOException e) { + throw new ServiceRuntimeException("Error while getting file bytes"); + } + } + + } + + + @Deprecated + @PutMapping(value = "/private/content/{id}") + @ResponseStatus(HttpStatus.OK) + @ApiOperation(httpMethod = "PUT", value = "Update content page", notes = "Updates a content page", + + response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + + public void updatePage(@PathVariable Long id, @RequestBody @Valid PersistableContentEntity page, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + page.setId(id); + //contentFacade.saveContentPage(page, merchantStore, language); + } + + /** + * Deletes a content from CMS + * + * @param name + */ + @Deprecated + @DeleteMapping(value = "/private/content/{id}") + @ApiOperation(httpMethod = "DELETE", value = "Deletes a content from CMS", notes = "Delete a content box or page", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT") }) + public void deleteContent(Long id, @ApiIgnore MerchantStore merchantStore) { + contentFacade.delete(merchantStore, id); + } + + /* *//** + * Deletes a content from CMS + * + * @param name + *//* + * @DeleteMapping(value = "/private/content/page/{id}") + * + * @ApiOperation(httpMethod = "DELETE", value = + * "Deletes a file from CMS", notes = "Delete a file from server", + * response = Void.class) + * + * @ApiImplicitParams({ + * + * @ApiImplicitParam(name = "store", dataType = "String", + * defaultValue = "DEFAULT")}) public void deleteFile( Long id, + * + * @ApiIgnore MerchantStore merchantStore) { + * contentFacade.deletePage(merchantStore, id); } + */ + + /** + * Deletes a file from CMS + * + * @param name + */ + @DeleteMapping(value = "/private/content/") + @ApiOperation(httpMethod = "DELETE", value = "Deletes a file from CMS", notes = "Delete a file from server", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void deleteFile(@Valid ContentName name, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + contentFacade.delete(merchantStore, name.getName(), name.getContentType()); + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/customer/AuthenticateCustomerApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/customer/AuthenticateCustomerApi.java new file mode 100755 index 0000000000..42cb2f5259 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/customer/AuthenticateCustomerApi.java @@ -0,0 +1,246 @@ +package com.salesmanager.shop.store.api.v1.customer; + +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +import org.apache.commons.lang3.Validate; +import org.apache.http.auth.AuthenticationException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.web.bind.annotation.RequestBody; +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.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.model.customer.PersistableCustomer; +import com.salesmanager.shop.store.api.exception.GenericRuntimeException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.UnauthorizedException; +import com.salesmanager.shop.store.controller.customer.facade.CustomerFacade; +import com.salesmanager.shop.store.controller.store.facade.StoreFacade; +import com.salesmanager.shop.store.controller.user.facade.UserFacade; +import com.salesmanager.shop.store.security.AuthenticationRequest; +import com.salesmanager.shop.store.security.AuthenticationResponse; +import com.salesmanager.shop.store.security.JWTTokenUtil; +import com.salesmanager.shop.store.security.PasswordRequest; +import com.salesmanager.shop.store.security.user.JWTUser; +import com.salesmanager.shop.utils.AuthorizationUtils; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@RestController +@RequestMapping("/api/v1") +@Api(tags = {"Customer authentication resource (Customer Authentication Api)"}) +@SwaggerDefinition(tags = { + @Tag(name = "Customer authentication resource", description = "Authenticates customer, register customer and reset customer password") +}) +public class AuthenticateCustomerApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticateCustomerApi.class); + + @Value("${authToken.header}") + private String tokenHeader; + + @Inject + private AuthenticationManager jwtCustomerAuthenticationManager; + + @Inject + private JWTTokenUtil jwtTokenUtil; + + @Inject + private UserDetailsService jwtCustomerDetailsService; + + @Inject + private CustomerFacade customerFacade; + + @Inject + private StoreFacade storeFacade; + + @Autowired + AuthorizationUtils authorizationUtils; + + @Autowired + private UserFacade userFacade; + + /** + * Create new customer for a given MerchantStore, then authenticate that customer + */ + @RequestMapping( value={"/customer/register"}, method=RequestMethod.POST, produces ={ "application/json" }) + @ResponseStatus(HttpStatus.CREATED) + @ApiOperation(httpMethod = "POST", value = "Registers a customer to the application", notes = "Used as self-served operation",response = AuthenticationResponse.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + @ResponseBody + public ResponseEntity register( + @Valid @RequestBody PersistableCustomer customer, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) throws Exception { + + + customer.setUserName(customer.getEmailAddress()); + + if(customerFacade.checkIfUserExists(customer.getUserName(), merchantStore)) { + //409 Conflict + throw new GenericRuntimeException("409", "Customer with email [" + customer.getEmailAddress() + "] is already registered"); + } + + Validate.notNull(customer.getUserName(),"Username cannot be null"); + Validate.notNull(customer.getBilling(),"Requires customer Country code"); + Validate.notNull(customer.getBilling().getCountry(),"Requires customer Country code"); + + customerFacade.registerCustomer(customer, merchantStore, language); + + // Perform the security + Authentication authentication = null; + try { + + authentication = jwtCustomerAuthenticationManager.authenticate( + new UsernamePasswordAuthenticationToken( + customer.getUserName(), + customer.getPassword() + ) + ); + + } catch(Exception e) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + if(authentication == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + SecurityContextHolder.getContext().setAuthentication(authentication); + + // Reload password post-security so we can generate token + final JWTUser userDetails = (JWTUser)jwtCustomerDetailsService.loadUserByUsername(customer.getUserName()); + final String token = jwtTokenUtil.generateToken(userDetails); + + // Return the token + return ResponseEntity.ok(new AuthenticationResponse(customer.getId(),token)); + + + } + + /** + * Authenticate a customer using username & password + * @param authenticationRequest + * @param device + * @return + * @throws AuthenticationException + */ + @RequestMapping(value = "/customer/login", method = RequestMethod.POST, produces ={ "application/json" }) + @ApiOperation(httpMethod = "POST", value = "Authenticates a customer to the application", notes = "Customer can authenticate after registration, request is {\"username\":\"admin\",\"password\":\"password\"}",response = ResponseEntity.class) + @ResponseBody + public ResponseEntity authenticate(@RequestBody @Valid AuthenticationRequest authenticationRequest) throws AuthenticationException { + + //TODO SET STORE in flow + // Perform the security + Authentication authentication = null; + try { + + + //to be used when username and password are set + authentication = jwtCustomerAuthenticationManager.authenticate( + new UsernamePasswordAuthenticationToken( + authenticationRequest.getUsername(), + authenticationRequest.getPassword() + ) + ); + + } catch(BadCredentialsException unn) { + return new ResponseEntity<>("{\"message\":\"Bad credentials\"}",HttpStatus.UNAUTHORIZED); + } catch(Exception e) { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + + if(authentication == null) { + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } + + SecurityContextHolder.getContext().setAuthentication(authentication); + + // Reload password post-security so we can generate token + // todo create one for social + final JWTUser userDetails = (JWTUser)jwtCustomerDetailsService.loadUserByUsername(authenticationRequest.getUsername()); + + final String token = jwtTokenUtil.generateToken(userDetails); + + // Return the token + return ResponseEntity.ok(new AuthenticationResponse(userDetails.getId(),token)); + } + + @RequestMapping(value = "/auth/customer/refresh", method = RequestMethod.GET, produces ={ "application/json" }) + public ResponseEntity refreshToken(HttpServletRequest request) { + String token = request.getHeader(tokenHeader); + + String username = jwtTokenUtil.getUsernameFromToken(token); + JWTUser user = (JWTUser) jwtCustomerDetailsService.loadUserByUsername(username); + + if (jwtTokenUtil.canTokenBeRefreshed(token, user.getLastPasswordResetDate())) { + String refreshedToken = jwtTokenUtil.refreshToken(token); + return ResponseEntity.ok(new AuthenticationResponse(user.getId(),refreshedToken)); + } else { + return ResponseEntity.badRequest().body(null); + } + } + + + + @RequestMapping(value = "/auth/customer/password", method = RequestMethod.POST, produces ={ "application/json" }) + @ApiOperation(httpMethod = "POST", value = "Sends a request to reset password", notes = "Password reset request is {\"username\":\"test@email.com\"}",response = ResponseEntity.class) + public ResponseEntity changePassword(@RequestBody @Valid PasswordRequest passwordRequest, HttpServletRequest request) { + + + try { + + MerchantStore merchantStore = storeFacade.getByCode(request); + + Customer customer = customerFacade.getCustomerByUserName(passwordRequest.getUsername(), merchantStore); + + if(customer == null){ + return ResponseEntity.notFound().build(); + } + + //need to validate if password matches + if(!customerFacade.passwordMatch(passwordRequest.getCurrent(), customer)) { + throw new ResourceNotFoundException("Username or password does not match"); + } + + if(!passwordRequest.getPassword().equals(passwordRequest.getRepeatPassword())) { + throw new ResourceNotFoundException("Both passwords do not match"); + } + + customerFacade.changePassword(customer, passwordRequest.getPassword()); + return ResponseEntity.ok(Void.class); + + } catch(Exception e) { + return ResponseEntity.badRequest().body("Exception when reseting password "+e.getMessage()); + } + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/customer/CustomerApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/customer/CustomerApi.java new file mode 100755 index 0000000000..5672ffa7fb --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/customer/CustomerApi.java @@ -0,0 +1,206 @@ +package com.salesmanager.shop.store.api.v1.customer; + +import java.security.Principal; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.customer.CustomerCriteria; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.model.customer.PersistableCustomer; +import com.salesmanager.shop.model.customer.ReadableCustomer; +import com.salesmanager.shop.populator.customer.ReadableCustomerList; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.api.exception.UnauthorizedException; +import com.salesmanager.shop.store.controller.customer.facade.CustomerFacade; +import com.salesmanager.shop.store.controller.user.facade.UserFacade; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@RestController +@RequestMapping(value = "/api/v1") +@Api(tags = { "Customer management resource (Customer Management Api)" }) +@SwaggerDefinition(tags = { @Tag(name = "Customer management resource", description = "Manage customers") }) +public class CustomerApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(CustomerApi.class); + + @Inject + private CustomerFacade customerFacade; + + @Autowired + private UserFacade userFacade; + + /** Create new customer for a given MerchantStore */ + @PostMapping("/private/customer") + @ApiOperation(httpMethod = "POST", value = "Creates a customer", notes = "Requires administration access", produces = "application/json", response = ReadableCustomer.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public ReadableCustomer create(@ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, + @Valid @RequestBody PersistableCustomer customer) { + return customerFacade.create(customer, merchantStore, language); + + } + + @PutMapping("/private/customer/{id}") + @ApiOperation(httpMethod = "PUT", value = "Updates a customer", notes = "Requires administration access", produces = "application/json", response = PersistableCustomer.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public PersistableCustomer update(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore, + @Valid @RequestBody PersistableCustomer customer) { + + customer.setId(id); + return customerFacade.update(customer, merchantStore); + } + + @PatchMapping("/private/customer/{id}/address") + @ApiOperation(httpMethod = "PATCH", value = "Updates a customer", notes = "Requires administration access", produces = "application/json", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public void updateAddress(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore, + @RequestBody PersistableCustomer customer) { + + customer.setId(id); + customerFacade.updateAddress(customer, merchantStore); + } + + @DeleteMapping("/private/customer/{id}") + @ApiOperation(httpMethod = "DELETE", value = "Deletes a customer", notes = "Requires administration access") + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public void delete(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + + customerFacade.deleteById(id); + } + + /** + * Get all customers + * + * @param start + * @param count + * @param request + * @return + * @throws Exception + */ + @GetMapping("/private/customers") + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public ReadableCustomerList list(@RequestParam(value = "page", required = false) Integer page, + @RequestParam(value = "count", required = false) Integer count, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + CustomerCriteria customerCriteria = createCustomerCriteria(page, count); + return customerFacade.getListByStore(merchantStore, customerCriteria, language); + } + + private CustomerCriteria createCustomerCriteria(Integer start, Integer count) { + CustomerCriteria customerCriteria = new CustomerCriteria(); + Optional.ofNullable(start).ifPresent(customerCriteria::setStartIndex); + Optional.ofNullable(count).ifPresent(customerCriteria::setMaxCount); + return customerCriteria; + } + + @GetMapping("/private/customer/{id}") + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public ReadableCustomer get(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + return customerFacade.getCustomerById(id, merchantStore, language); + } + + /** + * Get logged in customer profile + * + * @param merchantStore + * @param language + * @param request + * @return + */ + @GetMapping({ "/private/customer/profile", "/auth/customer/profile" }) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public ReadableCustomer getAuthUser(@ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, + HttpServletRequest request) { + Principal principal = request.getUserPrincipal(); + String userName = principal.getName(); + return customerFacade.getCustomerByNick(userName, merchantStore, language); + } + + @PatchMapping("/auth/customer/address") + @ApiOperation(httpMethod = "PATCH", value = "Updates a loged in customer address", notes = "Requires authentication", produces = "application/json", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public void updateAuthUserAddress(@ApiIgnore MerchantStore merchantStore, @RequestBody PersistableCustomer customer, + HttpServletRequest request) { + Principal principal = request.getUserPrincipal(); + String userName = principal.getName(); + + customerFacade.updateAddress(userName, customer, merchantStore); + + } + + @PatchMapping("/auth/customer/") + @ApiOperation(httpMethod = "PATCH", value = "Updates a loged in customer profile", notes = "Requires authentication", produces = "application/json", response = PersistableCustomer.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public PersistableCustomer update(@ApiIgnore MerchantStore merchantStore, + @Valid @RequestBody PersistableCustomer customer, HttpServletRequest request) { + + Principal principal = request.getUserPrincipal(); + String userName = principal.getName(); + + return customerFacade.update(userName, customer, merchantStore); + } + + @DeleteMapping("/auth/customer/") + @ApiOperation(httpMethod = "DELETE", value = "Deletes a loged in customer profile", notes = "Requires authentication", produces = "application/json", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public void delete(@ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, + HttpServletRequest request) { + + Principal principal = request.getUserPrincipal(); + String userName = principal.getName(); + + Customer customer; + try { + customer = customerFacade.getCustomerByUserName(userName, merchantStore); + if(customer == null) { + throw new ResourceNotFoundException("Customer [" + userName + "] not found"); + } + customerFacade.delete(customer); + } catch (Exception e) { + throw new ServiceRuntimeException("An error occured while deleting customer ["+userName+"]"); + } + + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/customer/CustomerNewsletterApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/customer/CustomerNewsletterApi.java new file mode 100755 index 0000000000..3169ff3bd6 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/customer/CustomerNewsletterApi.java @@ -0,0 +1,91 @@ +package com.salesmanager.shop.store.api.v1.customer; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; + +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.customer.PersistableCustomer; +import com.salesmanager.shop.model.customer.optin.PersistableCustomerOptin; +import com.salesmanager.shop.store.controller.customer.facade.CustomerFacade; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + + +/** + * Optin a customer to newsletter + * @author carlsamson + * + */ +@RestController +@RequestMapping(value = "/api/v1", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) +@Api(tags = { "Optin Customer to newsletter" }) +@SwaggerDefinition(tags = { @Tag(name = "Manage customer subscription to newsletter", description = "Manage customer subscription to newsletter") }) +public class CustomerNewsletterApi { + + @Inject + private CustomerFacade customerFacade; + + + /** Create new optin */ + @PostMapping("/newsletter") + @ApiOperation( + httpMethod = "POST", + value = "Creates a newsletter optin", + notes = "", + produces = "application/json") + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") + }) + public void create( + @Valid @RequestBody PersistableCustomerOptin optin, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + customerFacade.optinCustomer(optin, merchantStore); + } + + @PutMapping("/newsletter/{email}") + @ApiOperation( + httpMethod = "PUT", + value = "Updates a customer", + notes = "Requires administration access", + produces = "application/json", + response = PersistableCustomer.class) + public void update( + @PathVariable String email, + @Valid @RequestBody PersistableCustomer customer, + HttpServletRequest request, + HttpServletResponse response) { + throw new UnsupportedOperationException(); + } + + @DeleteMapping("/newsletter/{email}") + @ApiOperation( + httpMethod = "DELETE", + value = "Deletes a customer", + notes = "Requires administration access", + response = Void.class) + public ResponseEntity delete( + @PathVariable String email, HttpServletRequest request, HttpServletResponse response) { + throw new UnsupportedOperationException(); + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/customer/CustomerReviewApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/customer/CustomerReviewApi.java new file mode 100755 index 0000000000..6448b9640e --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/customer/CustomerReviewApi.java @@ -0,0 +1,106 @@ +package com.salesmanager.shop.store.api.v1.customer; + +import java.util.List; + +import javax.inject.Inject; +import javax.validation.Valid; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.customer.review.CustomerReviewService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.customer.PersistableCustomerReview; +import com.salesmanager.shop.model.customer.ReadableCustomerReview; +import com.salesmanager.shop.store.controller.customer.facade.CustomerFacade; +import com.salesmanager.shop.store.controller.store.facade.StoreFacade; +import com.salesmanager.shop.utils.LanguageUtils; + +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import springfox.documentation.annotations.ApiIgnore; + +@RestController +@RequestMapping("/api/v1") +public class CustomerReviewApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(CustomerReviewApi.class); + + @Inject + private CustomerFacade customerFacade; + + @Inject + private StoreFacade storeFacade; + + @Inject + private LanguageUtils languageUtils; + + @Inject + private CustomerService customerService; + + @Inject + private CustomerReviewService customerReviewService; + + /** + * Reviews made for a given customer + * + * @param id + * @param review + * @return + * @throws Exception + */ + @PostMapping("/private/customers/{id}/reviews") + @ResponseStatus(HttpStatus.CREATED) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") + }) + public PersistableCustomerReview create( + @PathVariable final Long id, + @Valid @RequestBody PersistableCustomerReview review, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + return customerFacade.createCustomerReview(id, review, merchantStore, language); + } + + @GetMapping("/customers/{id}/reviews") + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") + }) + public List getAll( + @PathVariable final Long id, @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + return customerFacade.getAllCustomerReviewsByReviewed(id, merchantStore, language); + } + + @PutMapping("/private/customers/{id}/reviews/{reviewid}") + public PersistableCustomerReview update( + @PathVariable final Long id, + @PathVariable final Long reviewId, + @Valid @RequestBody PersistableCustomerReview review, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + return customerFacade.updateCustomerReview(id, reviewId, review, merchantStore, language); + } + + @DeleteMapping("/private/customers/{id}/reviews/{reviewId}") + public void delete( + @PathVariable final Long id, + @PathVariable final Long reviewId, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + customerFacade.deleteCustomerReview(id, reviewId, merchantStore, language); + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/customer/ResetCustomerPasswordApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/customer/ResetCustomerPasswordApi.java new file mode 100644 index 0000000000..7be3222496 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/customer/ResetCustomerPasswordApi.java @@ -0,0 +1,128 @@ +package com.salesmanager.shop.store.api.v1.customer; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.store.api.exception.RestApiException; +import com.salesmanager.shop.store.security.PasswordRequest; +import com.salesmanager.shop.store.security.ResetPasswordRequest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@RestController +@RequestMapping(value = "/api/v1") +@Api(tags = { "Customer password management resource (User password Management Api)" }) +@SwaggerDefinition(tags = { + @Tag(name = "Customer password management resource", description = "Customer password management") }) +public class ResetCustomerPasswordApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(ResetCustomerPasswordApi.class); + + @Inject + private com.salesmanager.shop.store.controller.customer.facade.v1.CustomerFacade customerFacade; + + /** + * Request a reset password token + * + * @param merchantStore + * @param language + * @param user + * @param request + */ + @ResponseStatus(HttpStatus.OK) + @PostMapping(value = { "/customer/password/reset/request" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "POST", value = "Launch customer password reset flow", notes = "", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void passwordResetRequest(@ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, + @Valid @RequestBody ResetPasswordRequest customer) { + + customerFacade.requestPasswordReset(customer.getUsername(), customer.getReturnUrl(), merchantStore, language); + + } + + /** + * Verify a password token + * @param store + * @param token + * @param merchantStore + * @param language + * @param request + */ + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/customer/{store}/reset/{token}" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Validate customer password reset token", notes = "", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void passwordResetVerify( + @PathVariable String store, @PathVariable String token, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + /** + * Receives reset token Needs to validate if user found from token Needs + * to validate if token has expired + * + * If no problem void is returned otherwise throw OperationNotAllowed + * All of this in UserFacade + */ + + customerFacade.verifyPasswordRequestToken(token, store); + + } + + /** + * Change password + * @param passwordRequest + * @param store + * @param token + * @param merchantStore + * @param language + * @param request + */ + @RequestMapping(value = "/customer/{store}/password/{token}", method = RequestMethod.POST, produces = { + "application/json" }) + @ApiOperation(httpMethod = "POST", value = "Change customer password", response = Void.class) + public void changePassword( + @RequestBody @Valid PasswordRequest passwordRequest, + @PathVariable String store, + @PathVariable String token, @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, + HttpServletRequest request) { + + // validate password + if (StringUtils.isBlank(passwordRequest.getPassword()) + || StringUtils.isBlank(passwordRequest.getRepeatPassword())) { + throw new RestApiException("400", "Password don't match"); + } + + if (!passwordRequest.getPassword().equals(passwordRequest.getRepeatPassword())) { + throw new RestApiException("400", "Password don't match"); + } + + customerFacade.resetPassword(passwordRequest.getPassword(), token, store); + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/marketplace/MarketPlaceApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/marketplace/MarketPlaceApi.java new file mode 100755 index 0000000000..7be68ec94c --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/marketplace/MarketPlaceApi.java @@ -0,0 +1,114 @@ +package com.salesmanager.shop.store.api.v1.marketplace; + +import javax.inject.Inject; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.marketplace.ReadableMarketPlace; +import com.salesmanager.shop.model.marketplace.SignupStore; +import com.salesmanager.shop.model.user.ReadableUser; +import com.salesmanager.shop.store.api.exception.OperationNotAllowedException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.controller.marketplace.facade.MarketPlaceFacade; +import com.salesmanager.shop.store.controller.store.facade.StoreFacade; +import com.salesmanager.shop.store.controller.user.facade.UserFacade; +import com.salesmanager.shop.utils.LanguageUtils; + +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import springfox.documentation.annotations.ApiIgnore; + +@RestController +@RequestMapping("/api/v1") +public class MarketPlaceApi { + + @Autowired + private MarketPlaceFacade marketPlaceFacade; + + @Autowired + private UserFacade userFacade; + + @Inject + private StoreFacade storeFacade; + + @Inject + private LanguageUtils languageUtils; + + /** + * Get a marketplace from storeCode returns market place details and + * merchant store + */ + @GetMapping("/private/marketplace/{store}") + @ApiOperation(httpMethod = "GET", value = "Get market place meta-data", notes = "", produces = "application/json", response = ReadableMarketPlace.class) + public ReadableMarketPlace marketPlace(@PathVariable String store, + @RequestParam(value = "lang", required = false) String lang) { + + Language language = languageUtils.getServiceLanguage(lang); + return marketPlaceFacade.get(store, language); + } + + // signup new merchant + @PostMapping("/store/signup") + @ApiOperation(httpMethod = "POST", value = "Signup store", notes = "", produces = "application/json", response = Void.class) + public void signup(@RequestBody SignupStore store, @ApiIgnore Language language) { + + ReadableUser user = null; + try { + // check if user exists + user = userFacade.findByUserName(store.getEmail()); + + } catch (ResourceNotFoundException ignore) {//that is what will happen if user does not exists + } + + if (user != null) { + throw new OperationNotAllowedException( + "User [" + store.getEmail() + "] already exist and cannot be registered"); + } + + // check if store exists + if (storeFacade.existByCode(store.getCode())) { + throw new OperationNotAllowedException( + "Store [" + store.getCode() + "] already exist and cannot be registered"); + } + + // create user + + // create store + + // send notification + + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/store/{store}/signup/{token}" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Validate store signup token", notes = "", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void storeSignupVerify(@PathVariable String store, @PathVariable String token, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + /** + * Receives signup token. Needs to validate if a store + * to validate if token has expired + * + * If no problem void is returned otherwise throw OperationNotAllowed + */ + + //TBD + + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/order/OrderApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/order/OrderApi.java new file mode 100755 index 0000000000..b0ca074572 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/order/OrderApi.java @@ -0,0 +1,520 @@ +package com.salesmanager.shop.store.api.v1.order; + +import java.security.Principal; +import java.util.List; +import java.util.Locale; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; + +import com.salesmanager.core.business.services.order.OrderService; +import com.salesmanager.core.model.order.orderstatus.OrderStatus; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.jsoup.helper.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +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.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.shoppingcart.ShoppingCartService; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.order.OrderCriteria; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.model.customer.PersistableCustomer; +import com.salesmanager.shop.model.customer.ReadableCustomer; +import com.salesmanager.shop.model.order.v0.ReadableOrder; +import com.salesmanager.shop.model.order.v0.ReadableOrderList; +import com.salesmanager.shop.model.order.v1.PersistableAnonymousOrder; +import com.salesmanager.shop.model.order.v1.PersistableOrder; +import com.salesmanager.shop.model.order.v1.ReadableOrderConfirmation; +import com.salesmanager.shop.populator.customer.ReadableCustomerPopulator; +import com.salesmanager.shop.store.api.exception.GenericRuntimeException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.customer.facade.CustomerFacade; +import com.salesmanager.shop.store.controller.order.facade.OrderFacade; +import com.salesmanager.shop.store.security.services.CredentialsException; +import com.salesmanager.shop.store.security.services.CredentialsService; +import com.salesmanager.shop.utils.AuthorizationUtils; +import com.salesmanager.shop.utils.LocaleUtils; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@RestController +@RequestMapping("/api/v1") +@Api(tags = { "Ordering api (Order Flow Api)" }) +@SwaggerDefinition(tags = { @Tag(name = "Order flow resource", description = "Manage orders (create, list, get)") }) +public class OrderApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(OrderApi.class); + + @Inject + private CustomerService customerService; + + @Inject + private OrderFacade orderFacade; + + @Inject + private OrderService orderService; + + @Inject + private com.salesmanager.shop.store.controller.order.facade.v1.OrderFacade orderFacadeV1; + + @Inject + private ShoppingCartService shoppingCartService; + + @Autowired + private CustomerFacade customerFacade; + + @Autowired + private CustomerFacade customerFacadev1; //v1 version + + @Inject + private AuthorizationUtils authorizationUtils; + + @Inject + private CredentialsService credentialsService; + + private static final String DEFAULT_ORDER_LIST_COUNT = "25"; + + /** + * Get a list of orders for a given customer accept request parameter + * 'start' start index for count accept request parameter 'max' maximum + * number count, otherwise returns all Used for administrators + * + * @param response + * @return + * @throws Exception + */ + @RequestMapping(value = { "/private/orders/customers/{id}" }, method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public ReadableOrderList list(@PathVariable final Long id, + @RequestParam(value = "start", required = false) Integer start, + @RequestParam(value = "count", required = false) Integer count, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, HttpServletResponse response) throws Exception { + + Customer customer = customerService.getById(id); + + if (customer == null) { + LOGGER.error("Customer is null for id " + id); + response.sendError(404, "Customer is null for id " + id); + return null; + } + + if (start == null) { + start = new Integer(0); + } + if (count == null) { + count = new Integer(100); + } + + ReadableCustomer readableCustomer = new ReadableCustomer(); + ReadableCustomerPopulator customerPopulator = new ReadableCustomerPopulator(); + customerPopulator.populate(customer, readableCustomer, merchantStore, language); + + ReadableOrderList returnList = orderFacade.getReadableOrderList(merchantStore, customer, start, count, + language); + + List orders = returnList.getOrders(); + + if (!CollectionUtils.isEmpty(orders)) { + for (ReadableOrder order : orders) { + order.setCustomer(readableCustomer); + } + } + + return returnList; + } + + /** + * List orders for authenticated customers + * + * @param start + * @param count + * @param request + * @param response + * @return + * @throws Exception + */ + @RequestMapping(value = { "/auth/orders" }, method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public ReadableOrderList list(@RequestParam(value = "page", required = false) Integer page, + @RequestParam(value = "count", required = false) Integer count, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, HttpServletRequest request, HttpServletResponse response) throws Exception { + + Principal principal = request.getUserPrincipal(); + String userName = principal.getName(); + + Customer customer = customerService.getByNick(userName); + + if (customer == null) { + response.sendError(401, "Error while listing orders, customer not authorized"); + return null; + } + + if (page == null) { + page = new Integer(0); + } + if (count == null) { + count = new Integer(100); + } + + ReadableCustomer readableCustomer = new ReadableCustomer(); + ReadableCustomerPopulator customerPopulator = new ReadableCustomerPopulator(); + customerPopulator.populate(customer, readableCustomer, merchantStore, language); + + ReadableOrderList returnList = orderFacade.getReadableOrderList(merchantStore, customer, page, count, language); + + if (returnList == null) { + returnList = new ReadableOrderList(); + } + + List orders = returnList.getOrders(); + if (!CollectionUtils.isEmpty(orders)) { + for (ReadableOrder order : orders) { + order.setCustomer(readableCustomer); + } + } + return returnList; + } + + /** + * This method returns list of all the orders for a store.This is not + * bound to any specific stores and will get list of all the orders + * available for this instance + * + * @param start + * @param count + * @return List of orders + * @throws Exception + */ + @RequestMapping(value = { "/private/orders" }, method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + public ReadableOrderList list( + @RequestParam(value = "count", required = false, defaultValue = DEFAULT_ORDER_LIST_COUNT) Integer count, + @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, + @RequestParam(value = "name", required = false) String name, + @RequestParam(value = "id", required = false) Long id, + @RequestParam(value = "status", required = false) String status, + @RequestParam(value = "phone", required = false) String phone, + @RequestParam(value = "email", required = false) String email, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + OrderCriteria orderCriteria = new OrderCriteria(); + orderCriteria.setPageSize(count); + orderCriteria.setStartPage(page); + + orderCriteria.setCustomerName(name); + orderCriteria.setCustomerPhone(phone); + orderCriteria.setStatus(status); + orderCriteria.setEmail(email); + orderCriteria.setId(id); + + + String user = authorizationUtils.authenticatedUser(); + authorizationUtils.authorizeUser(user, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_ORDER, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()), merchantStore); + + ReadableOrderList orders = orderFacade.getReadableOrderList(orderCriteria, merchantStore); + + + return orders; + + } + + /** + * Order details + * @param id + * @param merchantStore + * @param language + * @return + */ + @RequestMapping(value = { "/private/orders/{id}" }, method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public ReadableOrder get( + @PathVariable final Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String user = authorizationUtils.authenticatedUser(); + authorizationUtils.authorizeUser(user, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_ORDER, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()), merchantStore); + + + ReadableOrder order = orderFacade.getReadableOrder(id, merchantStore, language); + + return order; + } + + /** + * Get a given order by id + * + * @param id + * @param request + * @param response + * @return + * @throws Exception + */ + @RequestMapping(value = { "/auth/orders/{id}" }, method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public ReadableOrder getOrder(@PathVariable final Long id, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, HttpServletRequest request, HttpServletResponse response) throws Exception { + Principal principal = request.getUserPrincipal(); + String userName = principal.getName(); + + Customer customer = customerService.getByNick(userName); + + if (customer == null) { + response.sendError(401, "Error while performing checkout customer not authorized"); + return null; + } + + ReadableOrder order = orderFacade.getReadableOrder(id, merchantStore, language); + + if (order == null) { + LOGGER.error("Order is null for id " + id); + response.sendError(404, "Order is null for id " + id); + return null; + } + + if (order.getCustomer() == null) { + LOGGER.error("Order is null for customer " + principal); + response.sendError(404, "Order is null for customer " + principal); + return null; + } + + if (order.getCustomer().getId() != null + && order.getCustomer().getId().longValue() != customer.getId().longValue()) { + LOGGER.error("Order is null for customer " + principal); + response.sendError(404, "Order is null for customer " + principal); + return null; + } + + return order; + } + + /** + * Action for performing a checkout on a given shopping cart + * + * @param id + * @param order + * @param request + * @param response + * @return + * @throws Exception + */ + @RequestMapping(value = { "/auth/cart/{code}/checkout" }, method = RequestMethod.POST) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public ReadableOrderConfirmation checkout( + @PathVariable final String code, //shopping cart + @Valid @RequestBody PersistableOrder order, // order + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletRequest request, + HttpServletResponse response, Locale locale) throws Exception { + + try { + Principal principal = request.getUserPrincipal(); + String userName = principal.getName(); + + Customer customer = customerService.getByNick(userName); + + if (customer == null) { + response.sendError(401, "Error while performing checkout customer not authorized"); + return null; + } + + ShoppingCart cart = shoppingCartService.getByCode(code, merchantStore); + if (cart == null) { + throw new ResourceNotFoundException("Cart code " + code + " does not exist"); + } + + order.setShoppingCartId(cart.getId()); + order.setCustomerId(customer.getId());//That is an existing customer purchasing + + Order modelOrder = orderFacade.processOrder(order, customer, merchantStore, language, locale); + Long orderId = modelOrder.getId(); + modelOrder.setId(orderId); + + + return orderFacadeV1.orderConfirmation(modelOrder, customer, merchantStore, language); + + + + } catch (Exception e) { + LOGGER.error("Error while processing checkout", e); + try { + response.sendError(503, "Error while processing checkout " + e.getMessage()); + } catch (Exception ignore) { + } + return null; + } + } + + /** + * Main checkout resource that will complete the order flow + * @param code + * @param order + * @param merchantStore + * @param language + * @return + */ + @RequestMapping(value = { "/cart/{code}/checkout" }, method = RequestMethod.POST) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public ReadableOrderConfirmation checkout( + @PathVariable final String code,//shopping cart + @Valid @RequestBody PersistableAnonymousOrder order,//order + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + Validate.notNull(order.getCustomer(), "Customer must not be null"); + + + ShoppingCart cart; + try { + cart = shoppingCartService.getByCode(code, merchantStore); + + if (cart == null) { + throw new ResourceNotFoundException("Cart code " + code + " does not exist"); + } + + //security password validation + PersistableCustomer presistableCustomer = order.getCustomer(); + if(!StringUtils.isBlank(presistableCustomer.getPassword())) { //validate customer password + credentialsService.validateCredentials(presistableCustomer.getPassword(), presistableCustomer.getRepeatPassword(), merchantStore, language); + } + + Customer customer = new Customer(); + customer = customerFacade.populateCustomerModel(customer, order.getCustomer(), merchantStore, language); + + if(!StringUtils.isBlank(presistableCustomer.getPassword())) { + //check if customer already exist + customer.setAnonymous(false); + customer.setNick(customer.getEmailAddress()); //username + if(customerFacadev1.checkIfUserExists(customer.getNick(), merchantStore)) { + //409 Conflict + throw new GenericRuntimeException("409", "Customer with email [" + customer.getEmailAddress() + "] is already registered"); + } + } + + + order.setShoppingCartId(cart.getId()); + + Order modelOrder = orderFacade.processOrder(order, customer, merchantStore, language, + LocaleUtils.getLocale(language)); + Long orderId = modelOrder.getId(); + //populate order confirmation + order.setId(orderId); + // set customer id + order.getCustomer().setId(modelOrder.getCustomerId()); + + return orderFacadeV1.orderConfirmation(modelOrder, customer, merchantStore, language); + + + } catch (Exception e) { + if(e instanceof CredentialsException) { + throw new GenericRuntimeException("412","Credentials creation Failed [" + e.getMessage() + "]"); + } + String message = e.getMessage(); + if(StringUtils.isBlank(message)) {//exception type + message = "APP-BACKEND"; + if(e.getCause() instanceof com.salesmanager.core.modules.integration.IntegrationException) { + message = "Integration problen occured to complete order"; + } + } + throw new ServiceRuntimeException("Error during checkout [" + message + "]", e); + } + + } + + @RequestMapping(value = { "/private/orders/{id}/customer" }, method = RequestMethod.PATCH) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public void updateOrderCustomer( + @PathVariable final Long id, + @Valid @RequestBody PersistableCustomer orderCustomer, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String user = authorizationUtils.authenticatedUser(); + authorizationUtils.authorizeUser(user, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_ORDER, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()), merchantStore); + + + orderFacade.updateOrderCustomre(id, orderCustomer, merchantStore); + return; + } + + @RequestMapping(value = { "/private/orders/{id}/status" }, method = RequestMethod.PUT) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public void updateOrderStatus( + @PathVariable final Long id, + @Valid @RequestBody String status, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String user = authorizationUtils.authenticatedUser(); + authorizationUtils.authorizeUser(user, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_ORDER, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()), merchantStore); + + Order order = orderService.getOrder(id, merchantStore); + if (order == null) { + throw new GenericRuntimeException("412", "Order not found [" + id + "]"); + } + + OrderStatus statusEnum = OrderStatus.valueOf(status); + + orderFacade.updateOrderStatus(order, statusEnum, merchantStore); + return; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/order/OrderPaymentApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/order/OrderPaymentApi.java new file mode 100755 index 0000000000..31d0bff8df --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/order/OrderPaymentApi.java @@ -0,0 +1,362 @@ +package com.salesmanager.shop.store.api.v1.order; + +import java.security.Principal; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +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.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.order.OrderService; +import com.salesmanager.core.business.services.payments.PaymentService; +import com.salesmanager.core.business.services.shoppingcart.ShoppingCartService; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.payments.Payment; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.payments.TransactionType; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.model.order.transaction.PersistablePayment; +import com.salesmanager.shop.model.order.transaction.ReadableTransaction; +import com.salesmanager.shop.model.order.v0.ReadableOrderList; +import com.salesmanager.shop.populator.order.transaction.PersistablePaymentPopulator; +import com.salesmanager.shop.populator.order.transaction.ReadableTransactionPopulator; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.controller.order.facade.OrderFacade; +import com.salesmanager.shop.utils.AuthorizationUtils; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@Controller +@RequestMapping("/api/v1") +@Api(tags = { "Order payment resource (Order payment Api)" }) +@SwaggerDefinition(tags = { @Tag(name = "Order payment resource", description = "Manage order payments") }) +public class OrderPaymentApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(OrderPaymentApi.class); + + @Inject + private CustomerService customerService; + + @Inject + private OrderService orderService; + + @Inject + private ShoppingCartService shoppingCartService; + + @Inject + private PricingService pricingService; + + @Inject + private PaymentService paymentService; + + @Inject + private OrderFacade orderFacade; + + @Inject + private AuthorizationUtils authorizationUtils; + + @RequestMapping(value = { "/cart/{code}/payment/init" }, method = RequestMethod.POST) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableTransaction init(@Valid @RequestBody PersistablePayment payment, @PathVariable String code, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) throws Exception { + + ShoppingCart cart = shoppingCartService.getByCode(code, merchantStore); + if (cart == null) { + throw new ResourceNotFoundException("Cart code " + code + " does not exist"); + } + + PersistablePaymentPopulator populator = new PersistablePaymentPopulator(); + populator.setPricingService(pricingService); + + Payment paymentModel = new Payment(); + + populator.populate(payment, paymentModel, merchantStore, language); + + Transaction transactionModel = paymentService.initTransaction(null, paymentModel, merchantStore); + + ReadableTransaction transaction = new ReadableTransaction(); + ReadableTransactionPopulator trxPopulator = new ReadableTransactionPopulator(); + trxPopulator.setOrderService(orderService); + trxPopulator.setPricingService(pricingService); + + trxPopulator.populate(transactionModel, transaction, merchantStore, language); + + return transaction; + + } + + @RequestMapping(value = { "/auth/cart/{code}/payment/init" }, method = RequestMethod.POST) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableTransaction init(@Valid @RequestBody PersistablePayment payment, @PathVariable String code, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, HttpServletRequest request, + HttpServletResponse response) throws Exception { + + try { + Principal principal = request.getUserPrincipal(); + String userName = principal.getName(); + + Customer customer = customerService.getByNick(userName); + + if (customer == null) { + response.sendError(401, "Error while initializing the payment customer not authorized"); + return null; + } + + ShoppingCart cart = shoppingCartService.getByCode(code, merchantStore); + if (cart == null) { + + throw new ResourceNotFoundException("Cart code " + code + " does not exist"); + } + + if (cart.getCustomerId() == null) { + response.sendError(404, "Cart code " + code + " does not exist for exist for user " + userName); + return null; + } + + if (cart.getCustomerId().longValue() != customer.getId().longValue()) { + response.sendError(404, "Cart code " + code + " does not exist for exist for user " + userName); + return null; + } + + PersistablePaymentPopulator populator = new PersistablePaymentPopulator(); + populator.setPricingService(pricingService); + + Payment paymentModel = new Payment(); + + populator.populate(payment, paymentModel, merchantStore, language); + + Transaction transactionModel = paymentService.initTransaction(customer, paymentModel, merchantStore); + + ReadableTransaction transaction = new ReadableTransaction(); + ReadableTransactionPopulator trxPopulator = new ReadableTransactionPopulator(); + trxPopulator.setOrderService(orderService); + trxPopulator.setPricingService(pricingService); + + trxPopulator.populate(transactionModel, transaction, merchantStore, language); + + return transaction; + + } catch (Exception e) { + LOGGER.error("Error while initializing the payment", e); + try { + response.sendError(503, "Error while initializing the payment " + e.getMessage()); + } catch (Exception ignore) { + } + return null; + } + } + + @RequestMapping(value = { "/private/orders/{id}/payment/nextTransaction" }, method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + + @ResponseBody + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public String nextTransaction( + @PathVariable final Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String user = authorizationUtils.authenticatedUser(); + authorizationUtils.authorizeUser(user, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_ORDER, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()), merchantStore); + + TransactionType transactionType = orderFacade.nextTransaction(id, merchantStore); + return "{\"transactionType\":\"" + transactionType.name() + "\"}"; + + } + + @RequestMapping(value = { "/private/orders/{id}/payment/transactions" }, method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + + @ResponseBody + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public List listTransactions( + @PathVariable final Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String user = authorizationUtils.authenticatedUser(); + authorizationUtils.authorizeUser(user, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_ORDER, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()), merchantStore); + + + return orderFacade.listTransactions(id, merchantStore); + + } + + /** + * An order can be pre-authorized but un captured. This metho returns all + * order subject to be capturable For a given time frame + * + * @param startDate + * @param endDate + * @param request + * @param response + * @return ReadableOrderList + * @throws Exception + */ + @RequestMapping(value = { "/private/orders/payment/capturable" }, method = RequestMethod.GET) + @ResponseStatus(HttpStatus.ACCEPTED) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableOrderList listCapturableOrders( + @RequestParam(value = "startDate", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate, + @RequestParam(value = "endDate", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, HttpServletRequest request, + HttpServletResponse response) { + + try { + + // if startdate or enddate are null use default range (last 24 + // hours) DD-1 to DD + Calendar cal = Calendar.getInstance(); + Date sDate = null; + + if (startDate != null) { + sDate = Date.from(startDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + } else { + cal.add(Calendar.DATE, -1); + sDate = cal.getTime(); + } + + Date eDate = null; + + if (endDate != null) { + eDate = Date.from(endDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + } else { + eDate = new Date(); + } + + ReadableOrderList returnList = orderFacade.getCapturableOrderList(merchantStore, sDate, eDate, language); + + return returnList; + + } catch (Exception e) { + LOGGER.error("Error while getting capturable payments", e); + try { + response.sendError(503, "Error while getting capturable payments " + e.getMessage()); + } catch (Exception ignore) { + } + return null; + } + } + + /** + * Capture payment transaction for a given order id + * + * @param id + * @param request + * @param response + * @return + * @throws Exception + */ + @RequestMapping(value = { "/private/orders/{id}/capture" }, method = RequestMethod.POST) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableTransaction capturePayment(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + /* + * try { + * + * // need order Order order = orderService.getById(id); + * + * if (order == null) { response.sendError(404, "Order id " + id + + * " does not exist"); return null; } + * + * // need customer Customer customer = + * customerService.getById(order.getCustomerId()); + * + * if (customer == null) { response.sendError(404, "Order id " + id + + * " contains an invalid customer " + order.getCustomerId()); return + * null; } + * + * ReadableTransaction transaction = + * orderFacade.captureOrder(merchantStore, order, customer, language); + * + * return transaction; + * + * } catch (Exception e) { LOGGER.error("Error while capturing payment", + * e); try { response.sendError(503, "Error while capturing payment " + + * e.getMessage()); } catch (Exception ignore) { } return null; } + */ + + return null; + } + + /** + * Refund payment + * + * @param id + * @param merchantStore + * @param language + * @return + */ + @RequestMapping(value = { "/private/orders/{id}/refund" }, method = RequestMethod.POST) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableTransaction refundPayment(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + return null; + } + + /** + * Capture payment + * + * @param id + * @param merchantStore + * @param language + * @return + */ + @RequestMapping(value = { "/private/orders/{id}/authorize" }, method = RequestMethod.POST) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableTransaction authorizePayment(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + return null; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/order/OrderShippingApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/order/OrderShippingApi.java new file mode 100755 index 0000000000..060e79933a --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/order/OrderShippingApi.java @@ -0,0 +1,290 @@ +package com.salesmanager.shop.store.api.v1.order; + +import java.security.Principal; +import java.util.List; +import java.util.Locale; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shipping.ShippingOption; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.model.shipping.ShippingSummary; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.shop.model.customer.address.AddressLocation; +import com.salesmanager.shop.model.order.shipping.ReadableShippingSummary; +import com.salesmanager.shop.populator.order.ReadableShippingSummaryPopulator; +import com.salesmanager.shop.store.controller.order.facade.OrderFacade; +import com.salesmanager.shop.store.controller.shoppingCart.facade.ShoppingCartFacade; +import com.salesmanager.shop.utils.LabelUtils; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@Controller +@RequestMapping("/api/v1") +@Api(tags = {"Shipping Quotes and Calculation resource (Shipping Api)"}) +@SwaggerDefinition(tags = { + @Tag(name = "Shipping Quotes and Calculation resource", description = "Get shipping quotes for public api and loged in customers") +}) +public class OrderShippingApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(OrderShippingApi.class); + + @Inject private CustomerService customerService; + + @Inject private OrderFacade orderFacade; + + @Inject private ShoppingCartFacade shoppingCartFacade; + + @Inject private LabelUtils messages; + + @Inject private PricingService pricingService; + + @Inject private CountryService countryService; + + /** + * Get shipping quote for a given shopping cart + * + * @param id + * @param request + * @param response + * @return + * @throws Exception + */ + @RequestMapping( + value = {"/auth/cart/{code}/shipping"}, + method = RequestMethod.GET) + @ResponseBody + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public ReadableShippingSummary shipping( + @PathVariable final String code, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletRequest request, + HttpServletResponse response) { + + try { + Locale locale = request.getLocale(); + Principal principal = request.getUserPrincipal(); + String userName = principal.getName(); + + // get customer id + Customer customer = customerService.getByNick(userName); + + if (customer == null) { + response.sendError(503, "Error while getting user details to calculate shipping quote"); + } + + ShoppingCart cart = shoppingCartFacade.getShoppingCartModel(code, merchantStore); + + if (cart == null) { + response.sendError(404, "Cart code " + code + " does not exist"); + } + + if (cart.getCustomerId() == null) { + response.sendError(404, "Cart code " + code + " does not exist for exist for user " + userName); + } + + if (cart.getCustomerId().longValue() != customer.getId().longValue()) { + response.sendError(404, "Cart code " + code + " does not exist for exist for user " + userName); + } + + ShippingQuote quote = orderFacade.getShippingQuote(customer, cart, merchantStore, language); + + ShippingSummary summary = orderFacade.getShippingSummary(quote, merchantStore, language); + + ReadableShippingSummary shippingSummary = new ReadableShippingSummary(); + ReadableShippingSummaryPopulator populator = new ReadableShippingSummaryPopulator(); + populator.setPricingService(pricingService); + populator.populate(summary, shippingSummary, merchantStore, language); + + List options = quote.getShippingOptions(); + + if (!CollectionUtils.isEmpty(options)) { + + for (ShippingOption shipOption : options) { + + StringBuilder moduleName = new StringBuilder(); + moduleName.append("module.shipping.").append(shipOption.getShippingModuleCode()); + + String carrier = + messages.getMessage( + moduleName.toString(), new String[] {merchantStore.getStorename()}, locale); + + String note = messages.getMessage(moduleName.append(".note").toString(), locale, ""); + + shipOption.setDescription(carrier); + shipOption.setNote(note); + + // option name + if (!StringUtils.isBlank(shipOption.getOptionCode())) { + // try to get the translate + StringBuilder optionCodeBuilder = new StringBuilder(); + try { + + optionCodeBuilder + .append("module.shipping.") + .append(shipOption.getShippingModuleCode()); + String optionName = messages.getMessage(optionCodeBuilder.toString(), locale); + shipOption.setOptionName(optionName); + } catch (Exception e) { // label not found + LOGGER.warn("No shipping code found for " + optionCodeBuilder.toString()); + } + } + } + + shippingSummary.setShippingOptions(options); + } + + return shippingSummary; + + } catch (Exception e) { + LOGGER.error("Error while getting shipping quote", e); + try { + response.sendError(503, "Error while getting shipping quote" + e.getMessage()); + } catch (Exception ignore) { + } + return null; + } + } + + /** + * Get shipping quote based on postal code + * @param code + * @param address + * @param merchantStore + * @param language + * @param request + * @param response + * @return + * @throws Exception + */ + @RequestMapping( + value = {"/cart/{code}/shipping"}, + method = RequestMethod.POST) + @ResponseBody + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public ReadableShippingSummary shipping( + @PathVariable final String code, + @RequestBody AddressLocation address, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletRequest request, + HttpServletResponse response) + throws Exception { + + try { + Locale locale = request.getLocale(); + + ShoppingCart cart = shoppingCartFacade.getShoppingCartModel(code, merchantStore); + + if (cart == null) { + response.sendError(404, "Cart id " + code + " does not exist"); + } + + + Delivery addr = new Delivery(); + addr.setPostalCode(address.getPostalCode()); + + Country c = countryService.getByCode(address.getCountryCode()); + + if(c==null) { + c = merchantStore.getCountry(); + } + addr.setCountry(c); + + + Customer temp = new Customer(); + temp.setAnonymous(true); + temp.setDelivery(addr); + + ShippingQuote quote = orderFacade.getShippingQuote(temp, cart, merchantStore, language); + + ShippingSummary summary = orderFacade.getShippingSummary(quote, merchantStore, language); + + ReadableShippingSummary shippingSummary = new ReadableShippingSummary(); + ReadableShippingSummaryPopulator populator = new ReadableShippingSummaryPopulator(); + populator.setPricingService(pricingService); + populator.populate(summary, shippingSummary, merchantStore, language); + + List options = quote.getShippingOptions(); + + if (!CollectionUtils.isEmpty(options)) { + + for (ShippingOption shipOption : options) { + + StringBuilder moduleName = new StringBuilder(); + moduleName.append("module.shipping.").append(shipOption.getShippingModuleCode()); + + String carrier = + messages.getMessage( + moduleName.toString(), new String[] {merchantStore.getStorename()}, locale); + + String note = messages.getMessage(moduleName.append(".note").toString(), locale, ""); + + shipOption.setDescription(carrier); + shipOption.setNote(note); + + // option name + if (!StringUtils.isBlank(shipOption.getOptionCode())) { + // try to get the translate + StringBuilder optionCodeBuilder = new StringBuilder(); + try { + + optionCodeBuilder + .append("module.shipping.") + .append(shipOption.getShippingModuleCode()); + String optionName = messages.getMessage(optionCodeBuilder.toString(), new String[]{merchantStore.getStorename()},locale); + shipOption.setOptionName(optionName); + } catch (Exception e) { // label not found + LOGGER.warn("No shipping code found for " + optionCodeBuilder.toString()); + } + } + } + + shippingSummary.setShippingOptions(options); + } + + return shippingSummary; + + } catch (Exception e) { + LOGGER.error("Error while getting shipping quote", e); + try { + response.sendError(503, "Error while getting shipping quote" + e.getMessage()); + } catch (Exception ignore) { + } + return null; + } + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/order/OrderStatusHistoryApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/order/OrderStatusHistoryApi.java new file mode 100644 index 0000000000..e54b322b11 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/order/OrderStatusHistoryApi.java @@ -0,0 +1,76 @@ +package com.salesmanager.shop.store.api.v1.order; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.inject.Inject; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +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.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; +import com.salesmanager.shop.constants.Constants; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.order.history.PersistableOrderStatusHistory; +import com.salesmanager.shop.model.order.history.ReadableOrderStatusHistory; +import com.salesmanager.shop.store.controller.order.facade.OrderFacade; +import com.salesmanager.shop.utils.AuthorizationUtils; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@RestController +@RequestMapping("/api/v1") +@Api(tags = { "Order status history api" }) +@SwaggerDefinition(tags = { + @Tag(name = "Order status history resource", description = "Related to OrderManagement api") }) +public class OrderStatusHistoryApi { + + @Inject + private OrderFacade orderFacade; + + @Inject + private AuthorizationUtils authorizationUtils; + + @RequestMapping(value = { "private/orders/{id}/history" }, method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + public List list(@PathVariable final Long id, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String user = authorizationUtils.authenticatedUser(); + authorizationUtils.authorizeUser(user, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_ORDER, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()), merchantStore); + + return orderFacade.getReadableOrderHistory(id, merchantStore, language); + + } + + @RequestMapping(value = { "private/orders/{id}/history" }, method = RequestMethod.POST) + @ResponseStatus(HttpStatus.CREATED) + @ApiOperation(httpMethod = "POST", value = "Add order history", notes = "Adds a new status to an order", produces = "application/json", response = Void.class) + @ResponseBody + public void create(@PathVariable final Long id, @RequestBody PersistableOrderStatusHistory history, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + String user = authorizationUtils.authenticatedUser(); + authorizationUtils.authorizeUser(user, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_ORDER, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()), merchantStore); + + // TODO validate date format + + orderFacade.createOrderStatus(history, id, merchantStore); + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/order/OrderTotalApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/order/OrderTotalApi.java new file mode 100755 index 0000000000..27f25e97ab --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/order/OrderTotalApi.java @@ -0,0 +1,224 @@ +package com.salesmanager.shop.store.api.v1.order; + +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +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.bind.annotation.ResponseBody; + +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.order.OrderService; +import com.salesmanager.core.business.services.shipping.ShippingQuoteService; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.OrderSummary; +import com.salesmanager.core.model.order.OrderTotalSummary; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shipping.ShippingSummary; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.shop.model.order.ReadableOrderTotalSummary; +import com.salesmanager.shop.populator.order.ReadableOrderSummaryPopulator; +import com.salesmanager.shop.store.controller.shoppingCart.facade.ShoppingCartFacade; +import com.salesmanager.shop.utils.LabelUtils; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@Controller +@RequestMapping("/api/v1") +@Api(tags = {"Order Total calculation for a given shopping cart (Order Total Api)"}) +@SwaggerDefinition(tags = { + @Tag(name = "Order Total resource", description = "Calculates order total for a giben shopping cart") +}) +public class OrderTotalApi { + + @Inject private ShoppingCartFacade shoppingCartFacade; + + @Inject private LabelUtils messages; + + @Inject private PricingService pricingService; + + @Inject private CustomerService customerService; + + @Inject private ShippingQuoteService shippingQuoteService; + + @Inject private OrderService orderService; + + private static final Logger LOGGER = LoggerFactory.getLogger(OrderTotalApi.class); + + /** + * This service calculates order total for a given shopping cart This method takes in + * consideration any applicable sales tax An optional request parameter accepts a quote id that + * was received using shipping api + * + * @param quote + * @param request + * @param response + * @return + * @throws Exception + */ + @RequestMapping( + value = {"/auth/cart/{id}/total"}, + method = RequestMethod.GET) + @ResponseBody + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public ReadableOrderTotalSummary payment( + @PathVariable final Long id, + @RequestParam(value = "quote", required = false) Long quote, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletRequest request, + HttpServletResponse response) { + + try { + Principal principal = request.getUserPrincipal(); + String userName = principal.getName(); + + Customer customer = customerService.getByNick(userName); + + if (customer == null) { + response.sendError(503, "Error while getting user details to calculate shipping quote"); + } + + ShoppingCart shoppingCart = shoppingCartFacade.getShoppingCartModel(id, merchantStore); + + if (shoppingCart == null) { + response.sendError(404, "Cart id " + id + " does not exist"); + return null; + } + + if (shoppingCart.getCustomerId() == null) { + response.sendError( + 404, "Cart id " + id + " does not exist for exist for user " + userName); + return null; + } + + if (shoppingCart.getCustomerId().longValue() != customer.getId().longValue()) { + response.sendError( + 404, "Cart id " + id + " does not exist for exist for user " + userName); + return null; + } + + ShippingSummary shippingSummary = null; + + // get shipping quote if asked for + if (quote != null) { + shippingSummary = shippingQuoteService.getShippingSummary(quote, merchantStore); + } + + OrderTotalSummary orderTotalSummary = null; + + OrderSummary orderSummary = new OrderSummary(); + orderSummary.setShippingSummary(shippingSummary); + List itemsSet = + new ArrayList(shoppingCart.getLineItems()); + orderSummary.setProducts(itemsSet); + + orderTotalSummary = + orderService.caculateOrderTotal(orderSummary, customer, merchantStore, language); + + ReadableOrderTotalSummary returnSummary = new ReadableOrderTotalSummary(); + ReadableOrderSummaryPopulator populator = new ReadableOrderSummaryPopulator(); + populator.setMessages(messages); + populator.setPricingService(pricingService); + populator.populate(orderTotalSummary, returnSummary, merchantStore, language); + + return returnSummary; + + } catch (Exception e) { + LOGGER.error("Error while calculating order summary", e); + try { + response.sendError(503, "Error while calculating order summary " + e.getMessage()); + } catch (Exception ignore) { + } + return null; + } + } + + /** + * Public api + * @param id + * @param quote + * @param merchantStore + * @param language + * @param response + * @return + */ + @RequestMapping( + value = {"/cart/{code}/total"}, + method = RequestMethod.GET) + @ResponseBody + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public ReadableOrderTotalSummary calculateTotal( + @PathVariable final String code, + @RequestParam(value = "quote", required = false) Long quote, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language,//possible postal code, province and country + HttpServletResponse response) { + + try { + ShoppingCart shoppingCart = shoppingCartFacade.getShoppingCartModel(code, merchantStore); + + if (shoppingCart == null) { + + response.sendError(404, "Cart code " + code + " does not exist"); + + return null; + } + + ShippingSummary shippingSummary = null; + + // get shipping quote if asked for + if (quote != null) { + shippingSummary = shippingQuoteService.getShippingSummary(quote, merchantStore); + } + + OrderTotalSummary orderTotalSummary = null; + + OrderSummary orderSummary = new OrderSummary(); + orderSummary.setShippingSummary(shippingSummary); + List itemsSet = + new ArrayList(shoppingCart.getLineItems()); + orderSummary.setProducts(itemsSet); + + orderTotalSummary = orderService.caculateOrderTotal(orderSummary, merchantStore, language); + + ReadableOrderTotalSummary returnSummary = new ReadableOrderTotalSummary(); + ReadableOrderSummaryPopulator populator = new ReadableOrderSummaryPopulator(); + populator.setMessages(messages); + populator.setPricingService(pricingService); + populator.populate(orderTotalSummary, returnSummary, merchantStore, language); + + return returnSummary; + + } catch (Exception e) { + LOGGER.error("Error while calculating order summary", e); + try { + response.sendError(503, "Error while calculating order summary " + e.getMessage()); + } catch (Exception ignore) { + } + return null; + } + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/payment/PaymentApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/payment/PaymentApi.java new file mode 100644 index 0000000000..9519d1171b --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/payment/PaymentApi.java @@ -0,0 +1,205 @@ +package com.salesmanager.shop.store.api.v1.payment; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.payments.PaymentService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.shop.model.system.IntegrationModuleConfiguration; +import com.salesmanager.shop.model.system.IntegrationModuleSummaryEntity; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +/** + * This API is for payment modules configurations. For payment of orders see + * order + * + * @author carlsamson + * + */ +@RestController +@RequestMapping(value = "/api/v1") +@Api(tags = { "Payment api" }) +@SwaggerDefinition(tags = { @Tag(name = "Payment management resources", description = "Payment management resources") }) +public class PaymentApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(PaymentApi.class); + + @Autowired + private PaymentService paymentService; + + /** + * Get available payment modules + * + * @param merchantStore + * @param language + * @return + */ + @GetMapping("/private/modules/payment") + @ApiOperation(httpMethod = "GET", value = "List list of payment modules", notes = "Requires administration access", produces = "application/json", response = List.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public List paymentModules( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + try { + List modules = paymentService.getPaymentMethods(merchantStore); + + // configured modules + Map configuredModules = paymentService + .getPaymentModulesConfigured(merchantStore); + return modules.stream().map(m -> integrationModule(m, configuredModules)).collect(Collectors.toList()); + + } catch (ServiceException e) { + LOGGER.error("Error getting payment modules", e); + throw new ServiceRuntimeException("Error getting payment modules", e); + } + + } + + @PostMapping(value = "/private/modules/payment") + public void configure( + @RequestBody IntegrationModuleConfiguration configuration, + @ApiIgnore MerchantStore merchantStore) { + + try { + + List modules = paymentService.getPaymentMethods(merchantStore); + + Map map = modules.stream() + .collect(Collectors.toMap(IntegrationModule::getCode, module -> module)); + + IntegrationModule config = map.get(configuration.getCode()); + + if (config == null) { + throw new ResourceNotFoundException("Payment module [" + configuration.getCode() + "] not found"); + } + + Map configuredModules = paymentService + .getPaymentModulesConfigured(merchantStore); + + IntegrationConfiguration integrationConfiguration = configuredModules.get(configuration.getCode()); + + if(integrationConfiguration == null) { + integrationConfiguration = new IntegrationConfiguration(); + integrationConfiguration.setModuleCode(configuration.getCode()); + } + + + integrationConfiguration.setActive(configuration.isActive()); + integrationConfiguration.setDefaultSelected(configuration.isDefaultSelected()); + integrationConfiguration.setIntegrationKeys(configuration.getIntegrationKeys()); + integrationConfiguration.setIntegrationOptions(configuration.getIntegrationOptions()); + + + paymentService.savePaymentModuleConfiguration(integrationConfiguration, merchantStore); + } catch (ServiceException e) { + LOGGER.error("Error getting payment modules", e); + throw new ServiceRuntimeException("Error saving payment module", e); + } + + } + + /** + * Get merchant payment module details + * + * @param code + * @param merchantStore + * @param language + * @return + */ + @GetMapping("/private/modules/payment/{code}") + @ApiOperation(httpMethod = "GET", value = "Payment module by code", produces = "application/json", response = List.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public IntegrationModuleConfiguration paymentModule(@PathVariable String code, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + try { + + // get module + IntegrationModule integrationModule = paymentService.getPaymentMethodByCode(merchantStore, code); + if (integrationModule == null) { + throw new ResourceNotFoundException("Payment module [" + code + "] not found"); + } + + IntegrationModuleConfiguration returnConfig = new IntegrationModuleConfiguration(); + returnConfig.setConfigurable(integrationModule.getConfigurable()); + returnConfig.setActive(false); + returnConfig.setDefaultSelected(false); + returnConfig.setCode(code); + + + + // configured modules + IntegrationConfiguration config = paymentService.getPaymentConfiguration(code, merchantStore); + + if(config == null) { + return returnConfig; + } + + + /** + * Build return object for now this is a read copy + */ + + + returnConfig.setActive(config.isActive()); + returnConfig.setDefaultSelected(config.isDefaultSelected()); + returnConfig.setCode(code); + returnConfig.setIntegrationKeys(config.getIntegrationKeys()); + returnConfig.setIntegrationOptions(config.getIntegrationOptions()); + + return returnConfig; + + } catch (ServiceException e) { + LOGGER.error("Error getting payment module [" + code + "]", e); + throw new ServiceRuntimeException("Error getting payment module [" + code + "]", e); + } + + } + + private IntegrationModuleSummaryEntity integrationModule(IntegrationModule module, + Map configuredModules) { + + IntegrationModuleSummaryEntity readable = null; + readable = new IntegrationModuleSummaryEntity(); + + readable.setCode(module.getCode()); + readable.setImage(module.getImage()); + readable.setBinaryImage(module.getBinaryImage()); + //readable.setRequiredKeys(module.getConfigurables()); + readable.setConfigurable(module.getConfigurable()); + if (configuredModules.containsKey(module.getCode())) { + readable.setConfigured(true); + if(configuredModules.get(module.getCode()).isActive()) { + readable.setActive(true); + } + } + return readable; + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductApi.java new file mode 100755 index 0000000000..44fc1cdab2 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductApi.java @@ -0,0 +1,513 @@ +package com.salesmanager.shop.store.api.v1.product; + +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +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.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +import com.salesmanager.core.business.services.catalog.category.CategoryService; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.ProductCriteria; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.LightPersistableProduct; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.model.catalog.product.ReadableProductList; +import com.salesmanager.shop.model.catalog.product.product.PersistableProduct; +import com.salesmanager.shop.model.entity.Entity; +import com.salesmanager.shop.model.entity.EntityExists; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.api.exception.UnauthorizedException; +import com.salesmanager.shop.store.controller.product.facade.ProductCommonFacade; +import com.salesmanager.shop.store.controller.product.facade.ProductFacade; +import com.salesmanager.shop.utils.ImageFilePath; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +/** + * API to create, read, update and delete a Product API. + * + * @author Carl Samson + */ +@Controller +@RequestMapping("/api/v1") +@Api(tags = { + "Product definition resource (Create udtate and delete product definition. Serves api v1 and v2 with backward compatibility)" }) +@SwaggerDefinition(tags = { + @Tag(name = "Product definition resource, add product to category", description = "View product, Add product, edit product and delete product") }) +public class ProductApi { + + @Inject + private CategoryService categoryService; + + @Inject + private ProductService productService; + + @Autowired + private ProductFacade productFacade; + + @Inject + private ProductCommonFacade productCommonFacade; + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductApi.class); + + /** + * Create product + * @param product + * @param merchantStore + * @param language + * @return Entity + */ + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = { "/private/product", "/auth/products" }, // private + // for + // adding + // products + method = RequestMethod.POST) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody Entity create(@Valid @RequestBody PersistableProduct product, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + Long id = productCommonFacade.saveProduct(merchantStore, product, language); + Entity returnEntity = new Entity(); + returnEntity.setId(id); + return returnEntity; + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{id}", "/auth/product/{id}" }, method = RequestMethod.PUT) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + @ApiOperation(httpMethod = "PUT", value = "Update product", notes = "", produces = "application/json", response = PersistableProduct.class) + public void update(@PathVariable Long id, + @Valid @RequestBody PersistableProduct product, @ApiIgnore MerchantStore merchantStore, + HttpServletRequest request, HttpServletResponse response) { + + try { + // Make sure we have consistency in this request + if (!id.equals(product.getId())) { + response.sendError(400, "Error url id does not match object id"); + } + + productCommonFacade.saveProduct(merchantStore, product, + merchantStore.getDefaultLanguage()); + } catch (Exception e) { + LOGGER.error("Error while updating product", e); + try { + response.sendError(503, "Error while updating product " + e.getMessage()); + } catch (Exception ignore) { + } + + } + } + + /** updates price quantity **/ + @ResponseStatus(HttpStatus.OK) + @PatchMapping(value = "/private/product/{id}", produces = { APPLICATION_JSON_VALUE }) + @ApiOperation(httpMethod = "PATCH", value = "Update product inventory", notes = "Updates product inventory", produces = "application/json", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public void update( + @PathVariable Long id, + @Valid @RequestBody + LightPersistableProduct product, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + productCommonFacade.update(id, product, merchantStore, language); + return; + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{id}", "/auth/product/{id}" }, method = RequestMethod.DELETE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void delete(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + productCommonFacade.deleteProduct(id, merchantStore); + } + + /** + * List products + * Filtering product lists based on product option and option value ?category=1 + * &manufacturer=2 &type=... &lang=en|fr NOT REQUIRED, will use request language + * &start=0 NOT REQUIRED, can be used for pagination &count=10 NOT REQUIRED, can + * be used to limit item count + * + * @param request + * @param response + * @return + * @throws Exception + */ + @RequestMapping(value = "/products", method = RequestMethod.GET) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableProductList list( + @RequestParam(value = "lang", required = false) String lang, + @RequestParam(value = "category", required = false) Long category, + @RequestParam(value = "name", required = false) String name, + @RequestParam(value = "sku", required = false) String sku, + @RequestParam(value = "manufacturer", required = false) Long manufacturer, + @RequestParam(value = "optionValues", required = false) List optionValueIds, + @RequestParam(value = "status", required = false) String status, + @RequestParam(value = "owner", required = false) Long owner, + @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, // current + @RequestParam(value = "origin", required = false, defaultValue = ProductCriteria.ORIGIN_SHOP) String origin, + // page + // 0 + // .. + // n + // allowing + // navigation + @RequestParam(value = "count", required = false, defaultValue = "100") Integer count, // count + @RequestParam(value = "slug", required = false) String slug, // category slug + @RequestParam(value = "available", required = false) Boolean available, + // per + // page + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, HttpServletRequest request, + HttpServletResponse response) throws Exception { + + ProductCriteria criteria = new ProductCriteria(); + + criteria.setOrigin(origin); + + // do not use legacy pagination anymore + if (lang != null) { + criteria.setLanguage(lang); + } else { + criteria.setLanguage(language.getCode()); + } + if (!StringUtils.isBlank(status)) { + criteria.setStatus(status); + } + // Start Category handling + List categoryIds = new ArrayList(); + if (slug != null) { + Category categoryBySlug = categoryService.getBySeUrl(merchantStore, slug); + categoryIds.add(categoryBySlug.getId()); + } + if (category != null) { + categoryIds.add(category); + } + if (categoryIds.size() > 0) { + criteria.setCategoryIds(categoryIds); + } + // End Category handling + + if (available != null && available) { + criteria.setAvailable(available); + } + + if (manufacturer != null) { + criteria.setManufacturerId(manufacturer); + } + + if (CollectionUtils.isNotEmpty(optionValueIds)) { + criteria.setOptionValueIds(optionValueIds); + } + + if (owner != null) { + criteria.setOwnerId(owner); + } + + if (page != null) { + criteria.setStartPage(page); + } + + if (count != null) { + criteria.setMaxCount(count); + } + + if (!StringUtils.isBlank(name)) { + criteria.setProductName(name); + } + + if (!StringUtils.isBlank(sku)) { + criteria.setCode(sku); + } + + // TODO + // RENTAL add filter by owner + // REPOSITORY to use the new filters + + try { + return productFacade.getProductListsByCriterias(merchantStore, language, criteria); + + } catch (Exception e) { + + LOGGER.error("Error while filtering products product", e); + try { + response.sendError(503, "Error while filtering products " + e.getMessage()); + } catch (Exception ignore) { + } + + return null; + } + } + + /** + * API for getting a product + * + * @param id + * @param lang ?lang=fr|en|... + * @param response + * @return ReadableProduct + * @throws Exception + *

    + * /api/product/123 + */ + @RequestMapping(value = "/product/{id}", method = RequestMethod.GET) + @ApiOperation(httpMethod = "GET", value = "Get a product by id", notes = "For administration and shop purpose. Specifying ?merchant is required otherwise it falls back to DEFAULT") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Single product found", response = ReadableProduct.class) }) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableProduct get(@PathVariable final Long id, @RequestParam(value = "lang", required = false) String lang, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, HttpServletResponse response) + throws Exception { + ReadableProduct product = productCommonFacade.getProduct(merchantStore, id, language); + + if (product == null) { + response.sendError(404, "Product not fount for id " + id); + return null; + } + + return product; + } + + /** + * Price calculation + * @param id + * @param variants + * @param merchantStore + * @param language + * @return + */ + /** + @RequestMapping(value = "/product/{id}/price", method = RequestMethod.POST) + @ApiOperation(httpMethod = "POST", value = "Calculate product price with variants", notes = "Product price calculation from variants") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Price calculated", response = ReadableProductPrice.class) }) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableProductPrice price(@PathVariable final Long id, + @RequestBody ProductPriceRequest variants, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + return productFacade.getProductPrice(id, variants, merchantStore, language); + + } + **/ + + /** + * API for getting a product + * + * @param friendlyUrl + * @param lang ?lang=fr|en + * @param response + * @return ReadableProduct + * @throws Exception + *

    + * /api/product/123 + */ + @RequestMapping(value = { "/product/slug/{friendlyUrl}", + "/product/friendly/{friendlyUrl}" }, method = RequestMethod.GET) + @ApiOperation(httpMethod = "GET", value = "Get a product by friendlyUrl (slug)", notes = "For administration and shop purpose. Specifying ?merchant is " + + "required otherwise it falls back to DEFAULT") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Single product found", response = ReadableProduct.class) }) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableProduct getByfriendlyUrl(@PathVariable final String friendlyUrl, + @RequestParam(value = "lang", required = false) String lang, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, HttpServletResponse response) throws Exception { + ReadableProduct product = productFacade.getProductBySeUrl(merchantStore, friendlyUrl, language); + + if (product == null) { + response.sendError(404, "Product not fount for id " + friendlyUrl); + return null; + } + + return product; + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/product/unique" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + @ApiOperation(httpMethod = "GET", value = "Check if product code already exists", notes = "", response = EntityExists.class) + public ResponseEntity exists(@RequestParam(value = "code") String code, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + boolean exists = productCommonFacade.exists(code, merchantStore); + return new ResponseEntity(new EntityExists(exists), HttpStatus.OK); + + } + + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = { "/private/product/{productId}/category/{categoryId}"}, method = RequestMethod.POST) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void addProductToCategory(@PathVariable Long productId, + @PathVariable Long categoryId, @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, + HttpServletResponse response) throws Exception { + + try { + // get the product + Product product = productService.getById(productId); + + if (product == null) { + throw new ResourceNotFoundException("Product id [" + productId + "] is not found"); + } + + if (product.getMerchantStore().getId().intValue() != merchantStore.getId().intValue()) { + throw new UnauthorizedException( + "Product id [" + productId + "] does not belong to store [" + merchantStore.getCode() + "]"); + } + + Category category = categoryService.getById(categoryId); + + if (category == null) { + throw new ResourceNotFoundException("Category id [" + categoryId + "] is not found"); + } + + if (category.getMerchantStore().getId().intValue() != merchantStore.getId().intValue()) { + throw new UnauthorizedException( + "Category id [" + categoryId + "] does not belong to store [" + merchantStore.getCode() + "]"); + } + + productCommonFacade.addProductToCategory(category, product, language); + + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{productId}/category/{categoryId}" }, method = RequestMethod.DELETE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void removeProductFromCategory(@PathVariable Long productId, + @PathVariable Long categoryId, @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + try { + Product product = productService.getById(productId); + + if (product == null) { + throw new ResourceNotFoundException("Product id [" + productId + "] is not found"); + } + + if (product.getMerchantStore().getId().intValue() != merchantStore.getId().intValue()) { + throw new UnauthorizedException( + "Product id [" + productId + "] does not belong to store [" + merchantStore.getCode() + "]"); + } + + Category category = categoryService.getById(categoryId); + + if (category == null) { + throw new ResourceNotFoundException("Category id [" + categoryId + "] is not found"); + } + + if (category.getMerchantStore().getId().intValue() != merchantStore.getId().intValue()) { + throw new UnauthorizedException( + "Category id [" + categoryId + "] does not belong to store [" + merchantStore.getCode() + "]"); + } + + productCommonFacade.removeProductFromCategory(category, product, language); + + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + } + + /** + * Change product sort order + * + * @param id + * @param position + * @param merchantStore + * @param language + * @throws IOException + */ + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{id}", "/auth/product/{id}" }, method = RequestMethod.PATCH) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + @ApiOperation(httpMethod = "POST", value = "Patch product sort order", notes = "Change product sortOrder") + public void changeProductOrder(@PathVariable Long id, + @RequestParam(value = "order", required = false, defaultValue = "0") Integer position, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) throws IOException { + + try { + + Product p = productService.getById(id); + + if (p == null) { + throw new ResourceNotFoundException( + "Product [" + id + "] not found for merchant [" + merchantStore.getCode() + "]"); + } + + if (p.getMerchantStore().getId() != merchantStore.getId()) { + throw new ResourceNotFoundException( + "Product [" + id + "] not found for merchant [" + merchantStore.getCode() + "]"); + } + + /** + * Change order + */ + p.setSortOrder(position); + + } catch (Exception e) { + LOGGER.error("Error while updating Product position", e); + throw new ServiceRuntimeException("Product [" + id + "] cannot be edited"); + } + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductAttributeOptionApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductAttributeOptionApi.java new file mode 100644 index 0000000000..1815ce6049 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductAttributeOptionApi.java @@ -0,0 +1,371 @@ +package com.salesmanager.shop.store.api.v1.product; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +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.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.multipart.MultipartFile; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductAttribute; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductOptionValue; +import com.salesmanager.shop.model.catalog.product.attribute.api.PersistableProductOptionEntity; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductAttributeEntity; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductAttributeList; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionEntity; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionList; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionValue; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionValueList; +import com.salesmanager.shop.model.entity.CodeEntity; +import com.salesmanager.shop.model.entity.Entity; +import com.salesmanager.shop.model.entity.EntityExists; +import com.salesmanager.shop.store.controller.product.facade.ProductOptionFacade; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@Controller +@RequestMapping("/api/v1") +@Api(tags = { "Product attributes and options / options values management resource (Product Option Management Api)" }) +@SwaggerDefinition(tags = { + @Tag(name = "Product attributes and options / options values management resource", description = "Edit product attributes / options and product option values") }) +public class ProductAttributeOptionApi { + + @Autowired + private ProductOptionFacade productOptionFacade; + + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = { "/private/product/option" }, method = RequestMethod.POST) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody ReadableProductOptionEntity createOption( + @Valid @RequestBody PersistableProductOptionEntity option, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, HttpServletRequest request, HttpServletResponse response) { + + ReadableProductOptionEntity entity = productOptionFacade.saveOption(option, merchantStore, language); + return entity; + + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/product/option/unique" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + @ApiOperation(httpMethod = "GET", value = "Check if option code already exists", notes = "", response = EntityExists.class) + public ResponseEntity optionExists(@RequestParam(value = "code") String code, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + boolean isOptionExist = productOptionFacade.optionExists(code, merchantStore); + return new ResponseEntity(new EntityExists(isOptionExist), HttpStatus.OK); + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/product/option/value/unique" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + @ApiOperation(httpMethod = "GET", value = "Check if option value code already exists", notes = "", response = EntityExists.class) + public ResponseEntity optionValueExists(@RequestParam(value = "code") String code, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + boolean isOptionExist = productOptionFacade.optionValueExists(code, merchantStore); + return new ResponseEntity(new EntityExists(isOptionExist), HttpStatus.OK); + } + + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = { "/private/product/option/value" }, method = RequestMethod.POST) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody ReadableProductOptionValue createOptionValue( + @Valid @RequestBody PersistableProductOptionValue optionValue, + //@RequestParam(name = "file", required = false) MultipartFile file, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletRequest request, + HttpServletResponse response) { + + ReadableProductOptionValue entity = productOptionFacade.saveOptionValue( optionValue, + merchantStore, language); + return entity; + + } + + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = { "/private/product/option/value/{id}/image" }, method = RequestMethod.POST) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void addOptionValueImage( + @PathVariable Long id, + @RequestParam(name = "file", required = true) MultipartFile file, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletRequest request, + HttpServletResponse response) { + + productOptionFacade.addOptionValueImage(file, id, merchantStore, language); + + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/option/value/{id}/image" }, method = RequestMethod.DELETE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void removeOptionValueImage( + @PathVariable Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletRequest request, HttpServletResponse response) { + + productOptionFacade.removeOptionValueImage(id, merchantStore, language); + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/option/{id}" }, method = RequestMethod.GET) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + @ResponseBody + public ReadableProductOptionEntity getOption(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, HttpServletRequest request, HttpServletResponse response) { + + return productOptionFacade.getOption(id, merchantStore, language); + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/option/value/{id}" }, method = RequestMethod.GET) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + @ResponseBody + public ReadableProductOptionValue getOptionValue(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, HttpServletRequest request, HttpServletResponse response) { + + return productOptionFacade.getOptionValue(id, merchantStore, language); + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/option/{optionId}" }, method = RequestMethod.PUT) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void updateOption(@Valid @RequestBody PersistableProductOptionEntity option, @PathVariable Long optionId, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, HttpServletRequest request, + HttpServletResponse response) { + option.setId(optionId); + productOptionFacade.saveOption(option, merchantStore, language); + return; + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/option/{optionId}" }, method = RequestMethod.DELETE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void deleteOption(@PathVariable Long optionId, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, HttpServletRequest request, HttpServletResponse response) { + + productOptionFacade.deleteOption(optionId, merchantStore); + return; + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/option/value/{id}" }, method = RequestMethod.PUT) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void updateOptionValue( + @PathVariable Long id, + @Valid @RequestBody PersistableProductOptionValue optionValue, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, HttpServletRequest request, + HttpServletResponse response) { + + optionValue.setId(id); + productOptionFacade.saveOptionValue(optionValue, merchantStore, language); + return; + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/option/value/{id}" }, method = RequestMethod.DELETE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void deleteOptionValue( + @PathVariable Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, HttpServletRequest request, + HttpServletResponse response) { + + productOptionFacade.deleteOptionValue(id, merchantStore); + return; + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/options" }, method = RequestMethod.GET) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody ReadableProductOptionList options( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + @RequestParam(value = "name", required = false) String name, + @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, + @RequestParam(value = "count", required = false, defaultValue = "10") Integer count) { + + return productOptionFacade.options(merchantStore, language, name, page, count); + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/options/values" }, method = RequestMethod.GET) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody ReadableProductOptionValueList optionsValues( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + @RequestParam(value = "name", required = false) String name, + @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, + @RequestParam(value = "count", required = false, defaultValue = "10") Integer count) { + + return productOptionFacade.optionValues(merchantStore, language, name, page, count); + + } + + /** + * Product attributes + * @param id + * @param merchantStore + * @param language + * @param request + * @param response + * @return + */ + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{id}/attributes" }, method = RequestMethod.GET) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + @ApiOperation(httpMethod = "GET", value = "Get product attributes", notes = "", + response = ReadableProductAttributeList.class) + public @ResponseBody ReadableProductAttributeList attributes( + @PathVariable Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, + @RequestParam(value = "count", required = false, defaultValue = "10") Integer count) { + + return productOptionFacade.getAttributesList(id, merchantStore, language, page, count); + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{id}/attribute/{attributeId}" }, method = RequestMethod.GET) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + @ApiOperation(httpMethod = "GET", value = "Get product attributes", notes = "", + response = EntityExists.class) + public @ResponseBody ReadableProductAttributeEntity getAttribute( + @PathVariable Long id, + @PathVariable Long attributeId, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, HttpServletRequest request, HttpServletResponse response) { + + ReadableProductAttributeEntity entity = productOptionFacade.getAttribute(id, attributeId, merchantStore, language); + return entity; + + } + + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = { "/private/product/{id}/attribute" }, method = RequestMethod.POST) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody Entity createAttribute( + @PathVariable Long id, + @Valid @RequestBody PersistableProductAttribute attribute, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletRequest request, + HttpServletResponse response) { + + ReadableProductAttributeEntity attributeEntity = productOptionFacade.saveAttribute(id, attribute, merchantStore, language); + + Entity entity = new Entity(); + entity.setId(attributeEntity.getId()); + return entity; + + + } + + /** + * Create multiple attributes + * @param id + * @param attributeId + * @param merchantStore + * @param language + * @param request + * @param response + */ + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = { "/private/product/{id}/attributes" }, method = RequestMethod.POST) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + @ApiOperation(httpMethod = "POST", value = "Saves multiple attributes", produces = "application/json", response = CodeEntity.class) + public List createAttributes( + @PathVariable Long id, + @Valid @RequestBody List attributes, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + + return productOptionFacade.createAttributes(attributes, id, merchantStore); + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{id}/attribute/{attributeId}" }, method = RequestMethod.PUT) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void updateAttribute(@PathVariable Long id, @Valid @RequestBody PersistableProductAttribute attribute, @PathVariable Long attributeId, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, HttpServletRequest request, + HttpServletResponse response) { + + attribute.setId(attributeId); + productOptionFacade.saveAttribute(id, attribute, merchantStore, language); + return; + + } + + + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{id}/attribute/{attributeId}" }, method = RequestMethod.DELETE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void deleteAttribute(@PathVariable Long id,@PathVariable Long attributeId, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, HttpServletRequest request, HttpServletResponse response) { + + productOptionFacade.deleteAttribute(id, attributeId, merchantStore); + return; + + } + +} \ No newline at end of file diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductGroupApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductGroupApi.java new file mode 100755 index 0000000000..e721c954cd --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductGroupApi.java @@ -0,0 +1,254 @@ +package com.salesmanager.shop.store.api.v1.product; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +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.ResponseStatus; + +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.ReadableProductList; +import com.salesmanager.shop.model.catalog.product.group.ProductGroup; +import com.salesmanager.shop.store.controller.items.facade.ProductItemsFacade; + +import antlr.collections.List; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +/** + * Used for product grouping such as featured items + * + * @author carlsamson + */ +@Controller +@RequestMapping("/api/v1") +@Api(tags = { "Product groups management resource (Product Groups Management Api)" }) +@SwaggerDefinition(tags = { + @Tag(name = "Product groups management resource", description = "Product groups management") }) +public class ProductGroupApi { + + @Inject private ProductService productService; + + @Inject private ProductItemsFacade productItemsFacade; + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductGroupApi.class); + + @ResponseStatus(HttpStatus.OK) + @PostMapping("/private/products/group") + @ApiOperation(httpMethod = "POST", value = "Create product group", notes = "", response = ProductGroup.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public @ResponseBody ProductGroup creteGroup( + @RequestBody ProductGroup group, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletResponse response) + throws Exception { + + return productItemsFacade.createProductGroup(group, merchantStore); + + } + + @ResponseStatus(HttpStatus.OK) + @PatchMapping("/private/products/group/{code}") + @ApiOperation(httpMethod = "PATCH", value = "Update product group visible flag", notes = "", response = ProductGroup.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public void updateGroup( + @RequestBody ProductGroup group, + @PathVariable String code, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletResponse response) + throws Exception { + + productItemsFacade.updateProductGroup(code, group, merchantStore); + + } + + @GetMapping("/private/product/groups") + @ApiOperation(httpMethod = "GET", value = "Get products groups for a given merchant", notes = "", response = List.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public @ResponseBody java.util.List list( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletResponse response) + throws Exception { + + return productItemsFacade.listProductGroups(merchantStore, language); + + } + + + /** + * Query for a product group public/product/group/{code}?lang=fr|en no lang it will take session + * lang or default store lang code can be any code used while creating product group, defeult + * being FEATURED + * + * @param store + * @param language + * @param groupCode + * @param request + * @param response + * @return + * @throws Exception + */ + @ResponseStatus(HttpStatus.OK) + @GetMapping("/products/group/{code}") + @ApiOperation(httpMethod = "GET", value = "Get products by group code", notes = "", response = ReadableProductList.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public @ResponseBody ReadableProductList getProductItemsByGroup( + @PathVariable final String code, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletResponse response) + throws Exception { + try { + ReadableProductList list = productItemsFacade.listItemsByGroup(code, merchantStore, language); + + if (list == null) { + response.sendError(404, "Group not fount for code " + code); + return null; + } + + return list; + + } catch (Exception e) { + LOGGER.error("Error while getting products", e); + response.sendError(503, "An error occured while retrieving products " + e.getMessage()); + } + + return null; + } + + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = "/private/products/{productId}/group/{code}", method = RequestMethod.POST) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public @ResponseBody ReadableProductList addProductToGroup( + @PathVariable Long productId, + @PathVariable String code, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletResponse response) { + + + Product product = null; + try { + // get the product + product = productService.getById(productId); + + if (product == null) { + response.sendError(404, "Product not fount for id " + productId); + return null; + } + + } catch (Exception e) { + LOGGER.error("Error while adding product to group", e); + try { + response.sendError(503, "Error while adding product to group " + e.getMessage()); + } catch (Exception ignore) { + } + + return null; + } + + ReadableProductList list = + productItemsFacade.addItemToGroup(product, code, merchantStore, language); + + return list; + + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping( + value = "/private/products/{productId}/group/{code}", + method = RequestMethod.DELETE) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public @ResponseBody ReadableProductList removeProductFromGroup( + @PathVariable Long productId, + @PathVariable String code, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletRequest request, + HttpServletResponse response) { + + try { + // get the product + Product product = productService.getById(productId); + + if (product == null) { + response.sendError(404, "Product not fount for id " + productId); + return null; + } + + ReadableProductList list = + productItemsFacade.removeItemFromGroup(product, code, merchantStore, language); + + return list; + + } catch (Exception e) { + LOGGER.error("Error while removing product from category", e); + try { + response.sendError(503, "Error while removing product from category " + e.getMessage()); + } catch (Exception ignore) { + } + + return null; + } + } + + @ResponseStatus(HttpStatus.OK) + @DeleteMapping("/products/group/{code}") + @ApiOperation(httpMethod = "DELETE", value = "Delete product group by group code", notes = "", response = Void.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public void deleteGroup( + @PathVariable final String code, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletResponse response) { + + productItemsFacade.deleteGroup(code, merchantStore); + + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductImageApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductImageApi.java new file mode 100755 index 0000000000..fc467d6009 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductImageApi.java @@ -0,0 +1,307 @@ +package com.salesmanager.shop.store.api.v1.product; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; + +import org.apache.commons.collections4.CollectionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +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.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.multipart.MultipartFile; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.image.ProductImageService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.image.ProductImage; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.catalog.ReadableProductImageMapper; +import com.salesmanager.shop.model.catalog.product.ReadableImage; +import com.salesmanager.shop.model.entity.NameEntity; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.api.exception.UnauthorizedException; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@Controller +@RequestMapping("/api/v1") +@Api(tags = { "Product images management. Add, remove and set the order of product images." }) +@SwaggerDefinition(tags = { + @Tag(name = "Product images management", description = "Add and remove products images. Change images sort order.") }) +public class ProductImageApi { + + @Inject + private ProductImageService productImageService; + + @Inject + private ProductService productService; + + @Autowired + private ReadableProductImageMapper readableProductImageMapper; + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductImageApi.class); + + /** + * To be used with MultipartFile + * + * @param id + * @param uploadfiles + * @param request + * @param response + * @throws Exception + */ + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = { "/private/product/{id}/image", "/auth/product/{id}/image" }, consumes = { + MediaType.MULTIPART_FORM_DATA_VALUE }, method = RequestMethod.POST) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void uploadImage( + @PathVariable Long id, + @RequestParam(value = "file", required = true) MultipartFile[] files, + @RequestParam(value = "order", required = false, defaultValue = "0") Integer position, + @RequestParam(value = "defaultImage", required = false, defaultValue = "false") boolean defaultImage, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) throws IOException { + + try { + + // get the product + Product product = productService.getById(id); + if (product == null) { + throw new ResourceNotFoundException("Product not found"); + } + + // security validation + // product belongs to merchant store + if (product.getMerchantStore().getId().intValue() != merchantStore.getId().intValue()) { + throw new UnauthorizedException("Resource not authorized for this merchant"); + } + + boolean hasDefaultImage = false; + Set images = product.getImages(); + + if (!defaultImage && !CollectionUtils.isEmpty(images)) { + for (ProductImage image : images) { + if (image.isDefaultImage()) { + hasDefaultImage = true; + break; + } + } + } + + List contentImagesList = new ArrayList(); + int sortOrder = position; + for (MultipartFile multipartFile : files) { + if (!multipartFile.isEmpty()) { + ProductImage productImage = new ProductImage(); + productImage.setImage(multipartFile.getInputStream()); + productImage.setProductImage(multipartFile.getOriginalFilename()); + productImage.setProduct(product); + + if (!hasDefaultImage) { + productImage.setDefaultImage(true); + hasDefaultImage = true; + } + productImage.setSortOrder(sortOrder); + position++; + contentImagesList.add(productImage); + } + } + + if (CollectionUtils.isNotEmpty(contentImagesList)) { + productImageService.addProductImages(product, contentImagesList); + } + + } catch (Exception e) { + LOGGER.error("Error while creating ProductImage", e); + throw new ServiceRuntimeException("Error while creating image"); + } + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/image/{id}", + "/auth/product/images/{id}" }, method = RequestMethod.DELETE) + public void deleteImage(@PathVariable Long id, HttpServletRequest request, HttpServletResponse response) + throws Exception { + + try { + ProductImage productImage = productImageService.getById(id); + + if (productImage != null) { + productImageService.delete(productImage); + } else { + response.sendError(404, "No ProductImage found for ID : " + id); + } + + } catch (Exception e) { + LOGGER.error("Error while deleting ProductImage", e); + try { + response.sendError(503, "Error while deleting ProductImage " + e.getMessage()); + } catch (Exception ignore) { + } + } + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{id}/image/{imageId}" }, method = RequestMethod.DELETE) + public void deleteImage(@PathVariable Long id, @PathVariable Long imageId, @Valid NameEntity imageName, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + + Optional productImage = productImageService.getProductImage(imageId, id, merchantStore); + + if (productImage.isPresent()) { + try { + productImageService.delete(productImage.get()); + } catch (ServiceException e) { + LOGGER.error("Error while deleting ProductImage", e); + throw new ServiceRuntimeException("ProductImage [" + imageId + "] cannot be deleted",e); + + } + } else { + throw new ResourceNotFoundException("Product image [" + imageId + + "] not found for product id [" + id + "] and merchant [" + merchantStore.getCode() + "]"); + } + + } + + + /** + * Get product images + * @param id + * @param imageId + * @param merchantStore + * @param language + * @return + */ + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/product/{productId}/images" }, method = RequestMethod.GET) + @ApiOperation(httpMethod = "GET", value = "Get images for a given product") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "List of ProductImage found", response = List.class) }) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public List images( + @PathVariable Long productId, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + + Product p = productService.getById(productId); + + if(p==null) { + throw new ResourceNotFoundException("Product images not found for product id [" + productId + + "] and merchant [" + merchantStore.getCode() + "]"); + } + + if(p.getMerchantStore().getId() != merchantStore.getId()) { + throw new ResourceNotFoundException("Product images not found for product id [" + productId + + "] and merchant [" + merchantStore.getCode() + "]"); + } + + List target = new ArrayList(); + + Set images = p.getImages(); + if(images!=null && images.size()>0) { + + + target = images.stream().map(i -> image(i, merchantStore, language)) + .sorted(Comparator.comparingInt(ReadableImage::getOrder)) + .collect(Collectors.toList()); + + + } + + return target; + + } + + private ReadableImage image(ProductImage image, MerchantStore store, Language language) { + return readableProductImageMapper.convert(image, store, language); + } + + + /** + * + * Patch image (change position) + * + * @param id + * @param files + * @param position + * @param merchantStore + * @param language + * @throws IOException + */ + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{id}/image/{imageId}", + "/auth/product/{id}/image/{id}" }, method = RequestMethod.PATCH) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void imageDetails(@PathVariable Long id, @PathVariable Long imageId, + @RequestParam(value = "order", required = false, defaultValue = "0") Integer position, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) throws IOException { + + try { + + Product p = productService.getById(id); + + if(p==null) { + throw new ResourceNotFoundException("Product image [" + imageId + "] not found for product id [" + id + + "] and merchant [" + merchantStore.getCode() + "]"); + } + + if(p.getMerchantStore().getId() != merchantStore.getId()) { + throw new ResourceNotFoundException("Product image [" + imageId + "] not found for product id [" + id + + "] and merchant [" + merchantStore.getCode() + "]"); + } + + Optional productImage = productImageService.getProductImage(imageId, id, merchantStore); + + if (productImage.isPresent()) { + productImage.get().setSortOrder(position); + productImageService.updateProductImage(p, productImage.get()); + } else { + throw new ResourceNotFoundException("Product image [" + imageId + "] not found for product id [" + id + + "] and merchant [" + merchantStore.getCode() + "]"); + } + + + + } catch (Exception e) { + LOGGER.error("Error while deleting ProductImage", e); + throw new ServiceRuntimeException("ProductImage [" + imageId + "] cannot be edited"); + } + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductInventoryApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductInventoryApi.java new file mode 100644 index 0000000000..1256e812b1 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductInventoryApi.java @@ -0,0 +1,122 @@ +package com.salesmanager.shop.store.api.v1.product; + +import javax.validation.Valid; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +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.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.inventory.PersistableInventory; +import com.salesmanager.shop.model.catalog.product.inventory.ReadableInventory; +import com.salesmanager.shop.model.entity.ReadableEntityList; +import com.salesmanager.shop.store.api.exception.RestApiException; +import com.salesmanager.shop.store.controller.product.facade.ProductInventoryFacade; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@Controller +@RequestMapping("/api/v1") +@Api(tags = { "Product inventory resource (Product Inventory Api)" }) +@SwaggerDefinition(tags = { + @Tag(name = "Product inventory resource", description = "Manage inventory for a given product") }) +public class ProductInventoryApi { + + @Autowired + private ProductInventoryFacade productInventoryFacade; + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductInventoryApi.class); + + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = { "/private/product/{productId}/inventory" }, method = RequestMethod.POST) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody ReadableInventory create(@PathVariable Long productId, + @Valid @RequestBody PersistableInventory inventory, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + inventory.setProductId(productId); + return productInventoryFacade.add(inventory, merchantStore, language); + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{productId}/inventory/{id}" }, method = RequestMethod.PUT) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void update( + @PathVariable Long productId, + @PathVariable Long id, + @Valid @RequestBody PersistableInventory inventory, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + inventory.setId(id); + inventory.setProductId(inventory.getProductId()); + inventory.setVariant(inventory.getVariant()); + inventory.setProductId(productId); + productInventoryFacade.update(inventory, merchantStore, language); + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{productId}/inventory/{id}" }, method = RequestMethod.DELETE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void delete( + @PathVariable Long productId, + @PathVariable Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + productInventoryFacade.delete(productId, id, merchantStore); + + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/product/{sku}/inventory" }) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody ReadableEntityList getBySku( + @PathVariable String sku, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, + @RequestParam(value = "count", required = false, defaultValue = "10") Integer count) { + + return productInventoryFacade.get(sku, merchantStore, language, page, count); + + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/product/inventory" }) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody ReadableEntityList getByProductId( + @RequestParam Long productId, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, + @RequestParam(value = "count", required = false, defaultValue = "10") Integer count) { + + if(productId == null) { + throw new RestApiException("Requires request parameter product id [/product/inventoty?productId"); + } + + return productInventoryFacade.get(productId, merchantStore, language, page, count); + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductManufacturerApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductManufacturerApi.java new file mode 100755 index 0000000000..b8f38069a5 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductManufacturerApi.java @@ -0,0 +1,231 @@ +package com.salesmanager.shop.store.api.v1.product; + +import java.util.List; +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +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.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import com.salesmanager.core.business.services.catalog.product.manufacturer.ManufacturerService; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.manufacturer.PersistableManufacturer; +import com.salesmanager.shop.model.catalog.manufacturer.ReadableManufacturer; +import com.salesmanager.shop.model.catalog.manufacturer.ReadableManufacturerList; +import com.salesmanager.shop.model.entity.EntityExists; +import com.salesmanager.shop.model.entity.ListCriteria; +import com.salesmanager.shop.store.controller.manufacturer.facade.ManufacturerFacade; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +/** + * Manufacturer management Collection, Manufacturer ... + * + * @author c.samson + */ +@Controller +@RequestMapping("/api/v1") +@Api(tags = { "Manufacturer / Brand management resource (Manufacturer / Brand Management Api)" }) +@SwaggerDefinition(tags = { + @Tag(name = "Manufacturer / Brand Management Api", description = "Edit Manufacturer / Brand") }) +public class ProductManufacturerApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductManufacturerApi.class); + + @Inject + private ManufacturerService manufacturerService; + + @Inject + private ManufacturerFacade manufacturerFacade; + + /** + * Method for creating a manufacturer + * + * @param manufacturer + * @param request + * @param response + * @return + * @throws Exception + */ + @RequestMapping(value = "/private/manufacturer", method = RequestMethod.POST) + @ResponseStatus(HttpStatus.CREATED) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public PersistableManufacturer create(@Valid @RequestBody PersistableManufacturer manufacturer, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, HttpServletResponse response) { + + try { + manufacturerFacade.saveOrUpdateManufacturer(manufacturer, merchantStore, language); + + return manufacturer; + + } catch (Exception e) { + LOGGER.error("Error while creating manufacturer", e); + try { + response.sendError(503, "Error while creating manufacturer " + e.getMessage()); + } catch (Exception ignore) { + } + + return null; + } + } + + @RequestMapping(value = "/manufacturer/{id}", method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableManufacturer get(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, HttpServletResponse response) { + + try { + ReadableManufacturer manufacturer = manufacturerFacade.getManufacturer(id, merchantStore, language); + + if (manufacturer == null) { + response.sendError(404, "No Manufacturer found for ID : " + id); + } + + return manufacturer; + + } catch (Exception e) { + LOGGER.error("Error while getting manufacturer", e); + try { + response.sendError(503, "Error while getting manufacturer " + e.getMessage()); + } catch (Exception ignore) { + } + } + + return null; + } + + + @RequestMapping(value = "/private/manufacturers", method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + @ApiOperation(httpMethod = "GET", value = "List manufacturers by store", notes = "This request supports paging or not. Paging supports page number and request count", response = ReadableManufacturerList.class) + public ReadableManufacturerList listByStore( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + @RequestParam(value = "name", required = false) String name, + @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, + @RequestParam(value = "count", required = false, defaultValue = "10") Integer count) { + + ListCriteria listCriteria = new ListCriteria(); + listCriteria.setName(name); + return manufacturerFacade.listByStore(merchantStore, language, listCriteria, page, count); + } + + + @RequestMapping(value = "/manufacturers", method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + @ApiOperation(httpMethod = "GET", value = "List manufacturers by store", notes = "This request supports paging or not. Paging supports page number and request count", response = ReadableManufacturerList.class) + public ReadableManufacturerList list(@ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, + @RequestParam(value = "name", required = false) String name, + @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, + @RequestParam(value = "count", required = false, defaultValue = "10") Integer count) { + + ListCriteria listCriteria = new ListCriteria(); + listCriteria.setName(name); + return manufacturerFacade.getAllManufacturers(merchantStore, language, listCriteria, page, count); + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/manufacturer/unique" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + @ApiOperation(httpMethod = "GET", value = "Check if manufacturer code already exists", notes = "", response = EntityExists.class) + public ResponseEntity exists(@RequestParam(value = "code") String code, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + boolean exists = manufacturerFacade.manufacturerExist(merchantStore, code); + return new ResponseEntity(new EntityExists(exists), HttpStatus.OK); + + } + + @RequestMapping(value = "/private/manufacturer/{id}", method = RequestMethod.PUT) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void update(@PathVariable Long id, + @Valid @RequestBody PersistableManufacturer manufacturer, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, HttpServletRequest request, HttpServletResponse response) { + + try { + manufacturer.setId(id); + manufacturerFacade.saveOrUpdateManufacturer(manufacturer, merchantStore, language); + } catch (Exception e) { + LOGGER.error("Error while creating manufacturer", e); + try { + response.sendError(503, "Error while creating manufacturer " + e.getMessage()); + } catch (Exception ignore) { + } + } + } + + @RequestMapping(value = "/private/manufacturer/{id}", method = RequestMethod.DELETE) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void delete(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, + HttpServletResponse response) { + + try { + Manufacturer manufacturer = manufacturerService.getById(id); + + if (manufacturer != null) { + manufacturerFacade.deleteManufacturer(manufacturer, merchantStore, language); + } else { + response.sendError(404, "No Manufacturer found for ID : " + id); + } + + } catch (Exception e) { + LOGGER.error("Error while deleting manufacturer id " + id, e); + try { + response.sendError(503, "Error while deleting manufacturer id " + id + " - " + e.getMessage()); + } catch (Exception ignore) { + } + } + } + + @RequestMapping(value = "/category/{id}/manufacturer", method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + @ApiOperation(httpMethod = "GET", value = "Get all manufacturers for all items in a given category", notes = "", produces = "application/json", response = List.class) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public List list(@PathVariable final Long id, // category + // id + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, HttpServletResponse response) + throws Exception { + + return manufacturerFacade.getByProductInCategory(merchantStore, language, id); + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductPriceApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductPriceApi.java new file mode 100644 index 0000000000..eb17d48893 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductPriceApi.java @@ -0,0 +1,183 @@ +package com.salesmanager.shop.store.api.v1.product; + +import java.util.List; + +import javax.validation.Valid; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +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.ResponseStatus; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.PersistableProductPrice; +import com.salesmanager.shop.model.catalog.product.ReadableProductPrice; +import com.salesmanager.shop.model.entity.Entity; +import com.salesmanager.shop.store.controller.product.facade.ProductPriceFacade; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +/** + * Use inventory + * @author carlsamson + * + */ + +@Controller +@RequestMapping("/api/v1") +@Api(tags = { "Product price api" }) +@SwaggerDefinition(tags = { @Tag(name = "Product price management", description = "Edit price and discount") }) +public class ProductPriceApi { + + + @Autowired + private ProductPriceFacade productPriceFacade;; + + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductApi.class); + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{sku}/inventory/{inventoryId}/price"}, + method = RequestMethod.POST) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody Entity save( + @PathVariable String sku, + @PathVariable Long inventoryId, + @Valid @RequestBody PersistableProductPrice price, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + price.setSku(sku); + price.setProductAvailabilityId(inventoryId); + + Long id = productPriceFacade.save(price, merchantStore); + return new Entity(id); + + + } + + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = { "/private/product/{sku}/price"}, + method = RequestMethod.POST) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody Entity save( + @PathVariable String sku, + @Valid @RequestBody PersistableProductPrice price, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + price.setSku(sku); + + Long id = productPriceFacade.save(price, merchantStore); + return new Entity(id); + + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{sku}/inventory/{inventoryId}/price/{priceId}"}, + method = RequestMethod.PUT) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void edit( + @PathVariable String sku, + @PathVariable Long inventoryId, + @PathVariable Long priceId, + @Valid @RequestBody PersistableProductPrice price, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + + price.setSku(sku); + price.setProductAvailabilityId(inventoryId); + price.setId(priceId); + productPriceFacade.save(price, merchantStore); + + + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{sku}/price/{priceId}"}, + method = RequestMethod.GET) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableProductPrice get( + @PathVariable String sku, + @PathVariable Long priceId, + @Valid @RequestBody PersistableProductPrice price, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + + price.setSku(sku); + price.setId(priceId); + + return productPriceFacade.get(sku, priceId, merchantStore, language); + + } + + @RequestMapping(value = { "/private/product/{sku}/inventory/{inventoryId}/price"}, + method = RequestMethod.GET) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public List list( + @PathVariable String sku, + @PathVariable Long inventoryId, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + + return productPriceFacade.list(sku, inventoryId, merchantStore, language); + + + } + + + @RequestMapping(value = { "/private/product/{sku}/prices"}, + method = RequestMethod.GET) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public List list( + @PathVariable String sku, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + + return productPriceFacade.list(sku, merchantStore, language); + + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{sku}/price/{priceId}"}, + method = RequestMethod.DELETE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void delete( + @PathVariable String sku, + @PathVariable Long priceId, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + + productPriceFacade.delete(priceId, sku, merchantStore); + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductPropertySetApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductPropertySetApi.java new file mode 100644 index 0000000000..6b51b8cb26 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductPropertySetApi.java @@ -0,0 +1,147 @@ +package com.salesmanager.shop.store.api.v1.product; + +import java.util.List; + +import javax.validation.Valid; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +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.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.attribute.optionset.PersistableProductOptionSet; +import com.salesmanager.shop.model.catalog.product.attribute.optionset.ReadableProductOptionSet; +import com.salesmanager.shop.model.entity.EntityExists; +import com.salesmanager.shop.store.controller.product.facade.ProductOptionSetFacade; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@Controller +@RequestMapping("/api/v1") +@Api(tags = { "Product property set regroupment management resource (Product Options Set Management Api)" }) +@SwaggerDefinition(tags = { + @Tag(name = "Product property set regroupment management resource resource", description = "Edit product property set") }) +public class ProductPropertySetApi { + + @Autowired + private ProductOptionSetFacade productOptionSetFacade; + + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = { "/private/product/property/set" }, method = RequestMethod.POST) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void create( + @Valid @RequestBody PersistableProductOptionSet optionSet, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + productOptionSetFacade.create(optionSet, merchantStore, language); + + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/product/property/set/unique" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + @ApiOperation(httpMethod = "GET", value = "Check if option set code already exists", notes = "", response = EntityExists.class) + public ResponseEntity exists( + @RequestParam(value = "code") String code, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + boolean isOptionExist = productOptionSetFacade.exists(code, merchantStore); + return new ResponseEntity(new EntityExists(isOptionExist), HttpStatus.OK); + } + + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/property/set/{id}" }, method = RequestMethod.GET) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + @ResponseBody + public ReadableProductOptionSet get( + @PathVariable Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + return productOptionSetFacade.get(id, merchantStore, language); + + } + + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/property/set/{id}" }, method = RequestMethod.PUT) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void update( + @Valid @RequestBody PersistableProductOptionSet option, + @PathVariable Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + option.setId(id); + productOptionSetFacade.update(id, option, merchantStore, language); + + } + + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/property/set/{id}" }, method = RequestMethod.DELETE) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void delete( + @PathVariable Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + productOptionSetFacade.delete(id, merchantStore); + + } + + /** + * Get property set by store + * filter by product type + * @param merchantStore + * @param language + * @return + */ + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/property/set" }, method = RequestMethod.GET) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody List list( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + @RequestParam(value = "productType", required = false) String type) { + + if(!StringUtils.isBlank(type)) { + return productOptionSetFacade.list(merchantStore, language, type); + } else { + return productOptionSetFacade.list(merchantStore, language); + } + + + } + + +} \ No newline at end of file diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductRelationshipApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductRelationshipApi.java new file mode 100755 index 0000000000..954e0f24b7 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductRelationshipApi.java @@ -0,0 +1,223 @@ +package com.salesmanager.shop.store.api.v1.product; + +import java.util.List; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +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.ResponseStatus; + +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.review.ProductReviewService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.store.controller.product.facade.ProductFacade; +import com.salesmanager.shop.store.controller.store.facade.StoreFacade; +import com.salesmanager.shop.utils.LanguageUtils; + +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import springfox.documentation.annotations.ApiIgnore; + +@Controller +@RequestMapping("/api/v1") +public class ProductRelationshipApi { + + @Inject private ProductFacade productFacade; + + @Inject private StoreFacade storeFacade; + + @Inject private LanguageUtils languageUtils; + + @Inject private ProductService productService; + + @Inject private ProductReviewService productReviewService; + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductRelationshipApi.class); + + /* @RequestMapping( value={"/private/products/{id}/related","/auth/products/{id}/related"}, method=RequestMethod.POST) + @ResponseStatus(HttpStatus.CREATED) + @ResponseBody + public PersistableProductReview create(@PathVariable final Long id, @Valid @RequestBody PersistableProductReview review, HttpServletRequest request, HttpServletResponse response) throws Exception { + + + try { + + MerchantStore merchantStore = storeFacade.getByCode(request); + Language language = languageUtils.getRESTLanguage(request, merchantStore); + + //rating already exist + ProductReview prodReview = productReviewService.getByProductAndCustomer(review.getProductId(), review.getCustomerId()); + if(prodReview!=null) { + response.sendError(500, "A review already exist for this customer and product"); + return null; + } + + //rating maximum 5 + if(review.getRating()>Constants.MAX_REVIEW_RATING_SCORE) { + response.sendError(503, "Maximum rating score is " + Constants.MAX_REVIEW_RATING_SCORE); + return null; + } + + review.setProductId(id); + + + + productFacade.saveOrUpdateReview(review, merchantStore, language); + + return review; + + } catch (Exception e) { + LOGGER.error("Error while saving product review",e); + try { + response.sendError(503, "Error while saving product review" + e.getMessage()); + } catch (Exception ignore) { + } + + return null; + } + }*/ + + @RequestMapping(value = "/product/{id}/related", method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + @ApiOperation( + httpMethod = "GET", + value = + "Get product related items. This is used for doing cross-sell and up-sell functionality on a product details page", + notes = "", + produces = "application/json", + response = List.class) + @ResponseBody + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public List getAll( + @PathVariable final Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletResponse response) + throws Exception { + + try { + // product exist + Product product = productService.getById(id); + + if (product == null) { + response.sendError(404, "Product id " + id + " does not exists"); + return null; + } + + List relatedItems = + productFacade.relatedItems(merchantStore, product, language); + + return relatedItems; + + } catch (Exception e) { + LOGGER.error("Error while getting product reviews", e); + try { + response.sendError(503, "Error while getting product reviews" + e.getMessage()); + } catch (Exception ignore) { + } + + return null; + } + } + + /* + @RequestMapping( value={"/private/products/{id}/reviews/{reviewid}","/auth/products/{id}/reviews/{reviewid}"}, method=RequestMethod.PUT) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + public PersistableProductReview update(@PathVariable final Long id, @PathVariable final Long reviewId, @Valid @RequestBody PersistableProductReview review, HttpServletRequest request, HttpServletResponse response) throws Exception { + + + try { + + MerchantStore merchantStore = storeFacade.getByCode(request); + Language language = languageUtils.getRESTLanguage(request, merchantStore); + + ProductReview prodReview = productReviewService.getById(reviewId); + if(prodReview==null) { + response.sendError(404, "Product review with id " + reviewId + " does not exist"); + return null; + } + + if(prodReview.getCustomer().getId().longValue() != review.getCustomerId().longValue()) { + response.sendError(404, "Product review with id " + reviewId + " does not exist"); + return null; + } + + //rating maximum 5 + if(review.getRating()>Constants.MAX_REVIEW_RATING_SCORE) { + response.sendError(503, "Maximum rating score is " + Constants.MAX_REVIEW_RATING_SCORE); + return null; + } + + review.setProductId(id); + + + productFacade.saveOrUpdateReview(review, merchantStore, language); + + return review; + + } catch (Exception e) { + LOGGER.error("Error while saving product review",e); + try { + response.sendError(503, "Error while saving product review" + e.getMessage()); + } catch (Exception ignore) { + } + + return null; + } + } + + @RequestMapping( value={"/private/products/{id}/reviews/{reviewid}","/auth/products/{id}/reviews/{reviewid}"}, method=RequestMethod.DELETE) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + public void delete(@PathVariable final Long id, @PathVariable final Long reviewId, HttpServletRequest request, HttpServletResponse response) throws Exception { + + + try { + + MerchantStore merchantStore = storeFacade.getByCode(request); + Language language = languageUtils.getRESTLanguage(request, merchantStore); + + ProductReview prodReview = productReviewService.getById(reviewId); + if(prodReview==null) { + response.sendError(404, "Product review with id " + reviewId + " does not exist"); + return; + } + + if(prodReview.getProduct().getId().longValue() != id.longValue()) { + response.sendError(404, "Product review with id " + reviewId + " does not exist"); + return; + } + + + productFacade.deleteReview(prodReview, merchantStore, language); + + + + } catch (Exception e) { + LOGGER.error("Error while deleting product review",e); + try { + response.sendError(503, "Error while deleting product review" + e.getMessage()); + } catch (Exception ignore) { + } + + return; + } + }*/ + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductReviewApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductReviewApi.java new file mode 100755 index 0000000000..688493efd8 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductReviewApi.java @@ -0,0 +1,240 @@ +package com.salesmanager.shop.store.api.v1.product; + +import java.util.List; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +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.ResponseStatus; + +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.review.ProductReviewService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.review.ProductReview; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.model.catalog.product.PersistableProductReview; +import com.salesmanager.shop.model.catalog.product.ReadableProductReview; +import com.salesmanager.shop.store.controller.product.facade.ProductCommonFacade; + +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import springfox.documentation.annotations.ApiIgnore; + +@Controller +@RequestMapping("/api/v1") +public class ProductReviewApi { + + @Inject private ProductCommonFacade productCommonFacade; + + @Inject private ProductService productService; + + @Inject private ProductReviewService productReviewService; + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductReviewApi.class); + + @RequestMapping( + value = { + "/private/products/{id}/reviews", + "/auth/products/{id}/reviews", + "/auth/products/{id}/reviews", + "/auth/products/{id}/reviews" + }, + method = RequestMethod.POST) + @ResponseStatus(HttpStatus.CREATED) + @ResponseBody + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public PersistableProductReview create( + @PathVariable final Long id, + @Valid @RequestBody PersistableProductReview review, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletRequest request, + HttpServletResponse response) { + + try { + // rating already exist + ProductReview prodReview = + productReviewService.getByProductAndCustomer( + review.getProductId(), review.getCustomerId()); + if (prodReview != null) { + response.sendError(500, "A review already exist for this customer and product"); + return null; + } + + // rating maximum 5 + if (review.getRating() > Constants.MAX_REVIEW_RATING_SCORE) { + response.sendError(503, "Maximum rating score is " + Constants.MAX_REVIEW_RATING_SCORE); + return null; + } + + review.setProductId(id); + + productCommonFacade.saveOrUpdateReview(review, merchantStore, language); + + return review; + + } catch (Exception e) { + LOGGER.error("Error while saving product review", e); + try { + response.sendError(503, "Error while saving product review" + e.getMessage()); + } catch (Exception ignore) { + } + + return null; + } + } + + @RequestMapping(value = "/product/{id}/reviews", method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public List getAll( + @PathVariable final Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletResponse response) { + + try { + // product exist + Product product = productService.getById(id); + + if (product == null) { + response.sendError(404, "Product id " + id + " does not exists"); + return null; + } + + List reviews = + productCommonFacade.getProductReviews(product, merchantStore, language); + + return reviews; + + } catch (Exception e) { + LOGGER.error("Error while getting product reviews", e); + try { + response.sendError(503, "Error while getting product reviews" + e.getMessage()); + } catch (Exception ignore) { + } + + return null; + } + } + + @RequestMapping( + value = { + "/private/products/{id}/reviews/{reviewid}", + "/auth/products/{id}/reviews/{reviewid}" + }, + method = RequestMethod.PUT) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public PersistableProductReview update( + @PathVariable final Long id, + @PathVariable final Long reviewId, + @Valid @RequestBody PersistableProductReview review, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletRequest request, + HttpServletResponse response) { + + try { + ProductReview prodReview = productReviewService.getById(reviewId); + if (prodReview == null) { + response.sendError(404, "Product review with id " + reviewId + " does not exist"); + return null; + } + + if (prodReview.getCustomer().getId().longValue() != review.getCustomerId().longValue()) { + response.sendError(404, "Product review with id " + reviewId + " does not exist"); + return null; + } + + // rating maximum 5 + if (review.getRating() > Constants.MAX_REVIEW_RATING_SCORE) { + response.sendError(503, "Maximum rating score is " + Constants.MAX_REVIEW_RATING_SCORE); + return null; + } + + review.setProductId(id); + + productCommonFacade.saveOrUpdateReview(review, merchantStore, language); + + return review; + + } catch (Exception e) { + LOGGER.error("Error while saving product review", e); + try { + response.sendError(503, "Error while saving product review" + e.getMessage()); + } catch (Exception ignore) { + } + + return null; + } + } + + @RequestMapping( + value = { + "/private/products/{id}/reviews/{reviewid}", + "/auth/products/{id}/reviews/{reviewid}" + }, + method = RequestMethod.DELETE) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public void delete( + @PathVariable final Long id, + @PathVariable final Long reviewId, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletResponse response) { + + try { + ProductReview prodReview = productReviewService.getById(reviewId); + if (prodReview == null) { + response.sendError(404, "Product review with id " + reviewId + " does not exist"); + return; + } + + if (prodReview.getProduct().getId().longValue() != id.longValue()) { + response.sendError(404, "Product review with id " + reviewId + " does not exist"); + return; + } + + productCommonFacade.deleteReview(prodReview, merchantStore, language); + + } catch (Exception e) { + LOGGER.error("Error while deleting product review", e); + try { + response.sendError(503, "Error while deleting product review" + e.getMessage()); + } catch (Exception ignore) { + } + + return; + } + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductTypeApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductTypeApi.java new file mode 100755 index 0000000000..10e5b8e119 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/product/ProductTypeApi.java @@ -0,0 +1,121 @@ +package com.salesmanager.shop.store.api.v1.product; + +import java.util.List; +import javax.inject.Inject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.type.PersistableProductType; +import com.salesmanager.shop.model.catalog.product.type.ReadableProductType; +import com.salesmanager.shop.model.catalog.product.type.ReadableProductTypeList; +import com.salesmanager.shop.model.entity.Entity; +import com.salesmanager.shop.model.entity.EntityExists; +import com.salesmanager.shop.store.controller.product.facade.ProductTypeFacade; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +/** + * API to create, read, update and delete a Product API to create Manufacturer + * + * @author Carl Samson + */ +@RestController +@RequestMapping("/api/v1") +@Api(tags = { "Product type resource (Product Type Api)" }) +@SwaggerDefinition(tags = { @Tag(name = "Product type resource", description = "Manage product types") }) +public class ProductTypeApi { + + @Inject + private ProductTypeFacade productTypeFacade; + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductTypeApi.class); + + @GetMapping(value = "/private/product/types", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get product types list", notes = "", produces = "application/json", response = List.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableProductTypeList list(@RequestParam(name = "count", defaultValue = "10") int count, + @RequestParam(name = "page", defaultValue = "0") int page, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + return productTypeFacade.getByMerchant(merchantStore, language, count, page); + + } + + @GetMapping(value = "/private/product/type/{id}", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get product type", notes = "", produces = "application/json", response = ReadableProductType.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableProductType get(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + return productTypeFacade.get(merchantStore, id, language); + + } + + @GetMapping(value = "/private/product/type/unique", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Verify if product type is unique", notes = "", produces = "application/json", response = ResponseEntity.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ResponseEntity exists(@RequestParam String code, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + boolean exists = productTypeFacade.exists(code, merchantStore, language); + return new ResponseEntity(new EntityExists(exists), HttpStatus.OK); + + } + + @PostMapping(value = "/private/product/type", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "POST", value = "Create product type", notes = "", produces = "application/json", response = Entity.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public Entity create(@RequestBody PersistableProductType type, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + Long id = productTypeFacade.save(type, merchantStore, language); + Entity entity = new Entity(); + entity.setId(id); + return entity; + + } + + @PutMapping(value = "/private/product/type/{id}", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "PUT", value = "Update product type", notes = "", produces = "application/json", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void update(@RequestBody PersistableProductType type, @PathVariable Long id, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + productTypeFacade.update(type, id, merchantStore, language); + + } + + @DeleteMapping(value = "/private/product/type/{id}", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "DELETE", value = "Delete product type", notes = "", produces = "application/json", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void delete(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + productTypeFacade.delete(id, merchantStore, language); + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/references/ReferencesApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/references/ReferencesApi.java new file mode 100755 index 0000000000..a14b5bb161 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/references/ReferencesApi.java @@ -0,0 +1,104 @@ +package com.salesmanager.shop.store.api.v1.references; + +import java.util.Arrays; +import java.util.List; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.currency.Currency; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.references.MeasureUnit; +import com.salesmanager.shop.model.references.ReadableCountry; +import com.salesmanager.shop.model.references.ReadableZone; +import com.salesmanager.shop.model.references.SizeReferences; +import com.salesmanager.shop.model.references.WeightUnit; +import com.salesmanager.shop.store.controller.country.facade.CountryFacade; +import com.salesmanager.shop.store.controller.currency.facade.CurrencyFacade; +import com.salesmanager.shop.store.controller.language.facade.LanguageFacade; +import com.salesmanager.shop.store.controller.store.facade.StoreFacade; +import com.salesmanager.shop.store.controller.zone.facade.ZoneFacade; +import com.salesmanager.shop.utils.LanguageUtils; + +import springfox.documentation.annotations.ApiIgnore; + +/** + * Get system Language, Country and Currency objects + * + * @author c.samson + */ +@RestController +@RequestMapping("/api/v1") +public class ReferencesApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(ReferencesApi.class); + + + @Inject private StoreFacade storeFacade; + + @Inject private LanguageUtils languageUtils; + + @Inject private LanguageFacade languageFacade; + + @Inject private CountryFacade countryFacade; + + @Inject private ZoneFacade zoneFacade; + + @Inject private CurrencyFacade currencyFacade; + + /** + * Search languages by language code private/languages returns everything + * + * @return + */ + @GetMapping("/languages") + public List getLanguages() { + return languageFacade.getLanguages(); + } + + /** + * Returns a country with zones (provinces, states) supports language set in parameter + * ?lang=en|fr|ru... + * + * @param request + * @return + */ + @GetMapping("/country") + public List getCountry(@ApiIgnore Language language, HttpServletRequest request) { + MerchantStore merchantStore = storeFacade.getByCode(request); + return countryFacade.getListCountryZones(language, merchantStore); + } + + @GetMapping("/zones") + public List getZones( + @RequestParam("code") String code, @ApiIgnore Language language, HttpServletRequest request) { + MerchantStore merchantStore = storeFacade.getByCode(request); + return zoneFacade.getZones(code, language, merchantStore); + } + + /** + * Currency + * + * @return + */ + @GetMapping("/currency") + public List getCurrency() { + return currencyFacade.getList(); + } + + @GetMapping("/measures") + public SizeReferences measures() { + SizeReferences sizeReferences = new SizeReferences(); + sizeReferences.setMeasures(Arrays.asList(MeasureUnit.values())); + sizeReferences.setWeights(Arrays.asList(WeightUnit.values())); + return sizeReferences; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/search/SearchApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/search/SearchApi.java new file mode 100755 index 0000000000..827eb71096 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/search/SearchApi.java @@ -0,0 +1,73 @@ +package com.salesmanager.shop.store.api.v1.search; + +import java.util.List; + +import javax.inject.Inject; + +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.SearchProductRequest; +import com.salesmanager.shop.model.entity.ValueList; +import com.salesmanager.shop.store.controller.search.facade.SearchFacade; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import modules.commons.search.request.SearchItem; +import springfox.documentation.annotations.ApiIgnore; + +/** + * Api for searching shopizer catalog based on search term when filtering products based on product + * attribute is required, see /api/v1/product + * + * @author c.samson + */ +@RestController +@RequestMapping("/api/v1") +@Api(tags = {"Search products and search word/sentence completion functionality (Search Api)"}) +@SwaggerDefinition(tags = { + @Tag(name = "Search products resource", description = "Search products and search term completion functionality") +}) +public class SearchApi { + + @Inject private SearchFacade searchFacade; + + + /** + * Search products from underlying elastic search + */ + @PostMapping("/search") + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + + //TODO use total, count and page + public @ResponseBody List search( + @RequestBody SearchProductRequest searchRequest, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + return searchFacade.search(merchantStore, language, searchRequest); + } + + @PostMapping("/search/autocomplete") + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public @ResponseBody ValueList autocomplete( + @RequestBody SearchProductRequest searchRequest, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + return searchFacade.autocompleteRequest(searchRequest.getQuery(), merchantStore, language); + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/security/SecurityApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/security/SecurityApi.java new file mode 100755 index 0000000000..18bd964657 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/security/SecurityApi.java @@ -0,0 +1,119 @@ +package com.salesmanager.shop.store.api.v1.security; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import javax.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.business.services.user.GroupService; +import com.salesmanager.core.business.services.user.PermissionService; +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.model.user.Permission; +import com.salesmanager.shop.model.security.ReadableGroup; +import com.salesmanager.shop.model.security.ReadablePermission; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; + +/** + * Api for managing security + * + * @author carlsamson + * + */ +@RestController +@RequestMapping(value = "/api/v1/sec") +@Api(tags = { "Groups and permissions Api" }) +@SwaggerDefinition(tags = { + @Tag(name = "List of supported groups and permissions", description = "List groups and attached permissions for reference") }) +public class SecurityApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(SecurityApi.class); + + @Inject + private PermissionService permissionService; + + @Inject + private GroupService groupService; + + @ResponseStatus(HttpStatus.OK) + @GetMapping({ "/private/{group}/permissions" }) + @ApiOperation(httpMethod = "GET", value = "Get permissions by group", notes = "", produces = MediaType.APPLICATION_JSON_VALUE, response = List.class) + public List listPermissions(@PathVariable String group) { + + Group g = null; + try { + g = groupService.findByName(group); + if(g == null) { + throw new ResourceNotFoundException("Group [" + group + "] does not exist"); + } + } catch (Exception e) { + LOGGER.error("An error occured while getting group [" + group + "]",e); + throw new ServiceRuntimeException("An error occured while getting group [" + group + "]"); + } + Set permissions = g.getPermissions(); + List readablePermissions = new ArrayList(); + for (Permission permission : permissions) { + ReadablePermission readablePermission = new ReadablePermission(); + readablePermission.setName(permission.getPermissionName()); + readablePermission.setId(permission.getId()); + readablePermissions.add(readablePermission); + } + return readablePermissions; + + + } + + /** + * Permissions Requires service user authentication + * + * @return + */ + @GetMapping("/private/permissions") + public List permissions() { + List permissions = permissionService.list(); + List readablePermissions = new ArrayList(); + for (Permission permission : permissions) { + ReadablePermission readablePermission = new ReadablePermission(); + readablePermission.setName(permission.getPermissionName()); + readablePermission.setId(permission.getId()); + readablePermissions.add(readablePermission); + } + return readablePermissions; + } + + /** + * Load groups Requires service user authentication + * + * @return + */ + @GetMapping("/private/groups") + public List groups() { + List groups = groupService.list(); + List readableGroups = new ArrayList(); + for (Group group : groups) { + ReadableGroup readableGroup = new ReadableGroup(); + readableGroup.setName(group.getGroupName()); + readableGroup.setId(group.getId().longValue()); + readableGroup.setType(group.getGroupType().name()); + readableGroups.add(readableGroup); + } + return readableGroups; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/shipping/ShippingConfigurationApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/shipping/ShippingConfigurationApi.java new file mode 100644 index 0000000000..b2f5d11dea --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/shipping/ShippingConfigurationApi.java @@ -0,0 +1,321 @@ +package com.salesmanager.shop.store.api.v1.shipping; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +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.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.shipping.ShippingService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shipping.PackageDetails; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.core.model.system.IntegrationModule; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.model.references.PersistableAddress; +import com.salesmanager.shop.model.references.ReadableAddress; +import com.salesmanager.shop.model.system.IntegrationModuleConfiguration; +import com.salesmanager.shop.model.system.IntegrationModuleSummaryEntity; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.shipping.facade.ShippingFacade; +import com.salesmanager.shop.utils.AuthorizationUtils; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@RestController +@RequestMapping("/api/v1") +@Api(tags = { "Shipping configuration resource (Shipping Management Api)" }) +@SwaggerDefinition(tags = { + @Tag(name = "Shipping management resource", description = "Manage shipping configuration") }) +public class ShippingConfigurationApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(ShippingConfigurationApi.class); + + @Autowired + private AuthorizationUtils authorizationUtils; + + @Autowired + private ShippingFacade shippingFacade; + + @Autowired + private ShippingService shippingService; + + @ApiOperation(httpMethod = "GET", value = "Get shipping origin for a specific merchant store", notes = "", produces = "application/json", response = ReadableAddress.class) + @RequestMapping(value = { "/private/shipping/origin" }, method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + public ReadableAddress shippingOrigin(@ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + String user = authorizationUtils.authenticatedUser(); + authorizationUtils.authorizeUser(user, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_SHIPPING, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()), merchantStore); + + return shippingFacade.getShippingOrigin(merchantStore); + + } + + @RequestMapping(value = { "/private/shipping/origin" }, method = RequestMethod.POST) + @ResponseStatus(HttpStatus.OK) + public void saveShippingOrigin(@RequestBody PersistableAddress address, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String user = authorizationUtils.authenticatedUser(); + authorizationUtils.authorizeUser(user, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_SHIPPING, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()), merchantStore); + + shippingFacade.saveShippingOrigin(address, merchantStore); + + } + + // list packaging + @ApiOperation(httpMethod = "GET", value = "Get list of configured packages types for a specific merchant store", notes = "", produces = "application/json", response = List.class) + @RequestMapping(value = { "/private/shipping/packages" }, method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + public List listPackages(@ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + String user = authorizationUtils.authenticatedUser(); + authorizationUtils.authorizeUser(user, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_SHIPPING, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()), merchantStore); + + return shippingFacade.listPackages(merchantStore); + + } + + // get packaging + @ApiOperation(httpMethod = "GET", value = "Get package details", notes = "", produces = "application/json", response = PackageDetails.class) + @RequestMapping(value = { "/private/shipping/package/{code}" }, method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + public PackageDetails getPackage(@PathVariable String code, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String user = authorizationUtils.authenticatedUser(); + authorizationUtils.authorizeUser(user, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_SHIPPING, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()), merchantStore); + + return shippingFacade.getPackage(code, merchantStore); + + } + + // create packaging + @ApiOperation(httpMethod = "POST", value = "Create new package specification", notes = "", produces = "application/json", response = Void.class) + @RequestMapping(value = { "/private/shipping/package" }, method = RequestMethod.POST) + @ResponseStatus(HttpStatus.OK) + public void createPackage(@RequestBody PackageDetails details, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String user = authorizationUtils.authenticatedUser(); + authorizationUtils.authorizeUser(user, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_SHIPPING, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()), merchantStore); + + shippingFacade.createPackage(details, merchantStore); + + } + + // edit packaging + @ApiOperation(httpMethod = "PUT", value = "Edit package specification", notes = "", produces = "application/json", response = Void.class) + @RequestMapping(value = { "/private/shipping/package/{code}" }, method = RequestMethod.PUT) + @ResponseStatus(HttpStatus.OK) + public void updatePackage(@PathVariable String code, @RequestBody PackageDetails details, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + String user = authorizationUtils.authenticatedUser(); + authorizationUtils.authorizeUser(user, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_SHIPPING, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()), merchantStore); + + shippingFacade.updatePackage(code, details, merchantStore); + + } + + // delete packaging + @ApiOperation(httpMethod = "DELETE", value = "Delete a package specification", notes = "", produces = "application/json", response = Void.class) + @RequestMapping(value = { "/private/shipping/package/{code}" }, method = RequestMethod.DELETE) + @ResponseStatus(HttpStatus.OK) + public void deletePackage(@PathVariable String code, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String user = authorizationUtils.authenticatedUser(); + authorizationUtils.authorizeUser(user, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_SHIPPING, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()), merchantStore); + + shippingFacade.deletePackage(code, merchantStore); + + } + + /** + * Get available shipping modules + * + * @param merchantStore + * @param language + * @return + */ + @GetMapping("/private/modules/shipping") + @ApiOperation(httpMethod = "GET", value = "List list of shipping modules", notes = "Requires administration access", produces = "application/json", response = List.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public List shippingModules(@ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + try { + List modules = shippingService.getShippingMethods(merchantStore); + + // configured modules + Map configuredModules = shippingService + .getShippingModulesConfigured(merchantStore); + return modules.stream().map(m -> integrationModule(m, configuredModules)).collect(Collectors.toList()); + + } catch (ServiceException e) { + LOGGER.error("Error getting shipping modules", e); + throw new ServiceRuntimeException("Error getting shipping modules", e); + } + + } + + /** + * Get merchant shipping module details + * + * @param code + * @param merchantStore + * @param language + * @return + */ + @GetMapping("/private/modules/shipping/{code}") + @ApiOperation(httpMethod = "GET", value = "Shipping module by code", produces = "application/json", response = List.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public IntegrationConfiguration shippingModule(@PathVariable String code, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + try { + + // configured modules + List modules = + shippingService + .getShippingMethods(merchantStore); + + //check if exist + Optional checkIfExist = modules.stream().filter(m -> m.getCode().equals(code)).findAny(); + + if(!checkIfExist.isPresent()) { + throw new ResourceNotFoundException("Shipping module [" + code + "] not found"); + } + + IntegrationConfiguration config = shippingService.getShippingConfiguration(code, merchantStore); + if (config == null) { + config = new IntegrationConfiguration(); + } + + /** + * Build return object for now this is a read copy + */ + + config.setActive(config.isActive()); + config.setDefaultSelected(config.isDefaultSelected()); + config.setIntegrationKeys(config.getIntegrationKeys()); + config.setIntegrationOptions(config.getIntegrationOptions()); + + return config; + + } catch (ServiceException e) { + LOGGER.error("Error getting shipping module [" + code + "]", e); + throw new ServiceRuntimeException("Error getting shipping module [" + code + "]", e); + } + + } + + @PostMapping(value = "/private/modules/shipping") + public void configure(@RequestBody IntegrationModuleConfiguration configuration, + @ApiIgnore MerchantStore merchantStore) { + + try { + + List modules = shippingService.getShippingMethods(merchantStore); + + Map map = modules.stream() + .collect(Collectors.toMap(IntegrationModule::getCode, module -> module)); + + IntegrationModule config = map.get(configuration.getCode()); + + if (config == null) { + throw new ResourceNotFoundException("Shipping module [" + configuration.getCode() + "] not found"); + } + + Map configuredModules = shippingService + .getShippingModulesConfigured(merchantStore); + + IntegrationConfiguration integrationConfiguration = configuredModules.get(configuration.getCode()); + + if (integrationConfiguration == null) { + integrationConfiguration = new IntegrationConfiguration(); + } + + /** + * Build return object for now this is a read copy + */ + + integrationConfiguration.setActive(configuration.isActive()); + integrationConfiguration.setDefaultSelected(configuration.isDefaultSelected()); + integrationConfiguration.setIntegrationKeys(configuration.getIntegrationKeys()); + integrationConfiguration.setIntegrationOptions(configuration.getIntegrationOptions()); + + shippingService.saveShippingQuoteModuleConfiguration(integrationConfiguration, merchantStore); + + } catch (ServiceException e) { + LOGGER.error("Error saving shipping modules", e); + throw new ServiceRuntimeException("Error saving shipping module", e); + } + + } + + private IntegrationModuleSummaryEntity integrationModule(IntegrationModule module, + Map configuredModules) { + + IntegrationModuleSummaryEntity readable = null; + readable = new IntegrationModuleSummaryEntity(); + + readable.setCode(module.getCode()); + readable.setImage(module.getImage()); + if (configuredModules.containsKey(module.getCode())) { + IntegrationConfiguration conf = configuredModules.get(module.getCode()); + readable.setConfigured(true); + if(conf.isActive()) { + readable.setActive(true); + } + } + return readable; + + } + + // Module configuration + /** + * private String moduleCode; private boolean active; private boolean + * defaultSelected; private Map integrationKeys = new + * HashMap(); private Map> + * integrationOptions = new HashMap>(); private String + * environment; + * + * moduleCode:CODE, active:true, defaultSelected:false, environment: "TEST", + * integrationKeys { "key":"value", "anotherkey":"anothervalue"... } + */ + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/shipping/ShippingExpeditionApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/shipping/ShippingExpeditionApi.java new file mode 100644 index 0000000000..7285a94d1d --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/shipping/ShippingExpeditionApi.java @@ -0,0 +1,91 @@ +package com.salesmanager.shop.store.api.v1.shipping; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestBody; +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.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.model.references.ReadableCountry; +import com.salesmanager.shop.model.shipping.ExpeditionConfiguration; +import com.salesmanager.shop.store.controller.shipping.facade.ShippingFacade; +import com.salesmanager.shop.utils.AuthorizationUtils; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@RestController +@RequestMapping("/api/v1") +@Api(tags = { "Shipping - Expedition management resource (Shipping Management Api) - ship to country" }) +@SwaggerDefinition(tags = { @Tag(name = "Shipping - Expedition management resource", description = "Manage shipping expedition") }) +public class ShippingExpeditionApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(ShippingExpeditionApi.class); + + @Autowired + private AuthorizationUtils authorizationUtils; + + @Autowired + private ShippingFacade shippingFacade; + + @RequestMapping(value = { "/private/shipping/expedition" }, method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + public ExpeditionConfiguration expedition( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + + String user = authorizationUtils.authenticatedUser(); + authorizationUtils.authorizeUser(user, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_SHIPPING, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()), merchantStore); + + return shippingFacade.getExpeditionConfiguration(merchantStore, language); + + } + + @GetMapping("/shipping/country") + public List + getCountry( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + return shippingFacade.shipToCountry(merchantStore, language); + } + + + @RequestMapping(value = { "/private/shipping/expedition" }, method = RequestMethod.POST) + @ResponseStatus(HttpStatus.OK) + @ResponseBody + public void saveExpedition( + @RequestBody ExpeditionConfiguration expedition, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + + String user = authorizationUtils.authenticatedUser(); + authorizationUtils.authorizeUser(user, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_SHIPPING, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList()), merchantStore); + + shippingFacade.saveExpeditionConfiguration(expedition, merchantStore); + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/shoppingCart/ShoppingCartApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/shoppingCart/ShoppingCartApi.java new file mode 100755 index 0000000000..7c300f2571 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/shoppingCart/ShoppingCartApi.java @@ -0,0 +1,303 @@ +package com.salesmanager.shop.store.api.v1.shoppingCart; + +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import java.security.Principal; +import java.util.Arrays; +import java.util.Optional; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +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.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.shoppingcart.PersistableShoppingCartItem; +import com.salesmanager.shop.model.shoppingcart.ReadableShoppingCart; +import com.salesmanager.shop.store.api.exception.OperationNotAllowedException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.customer.facade.v1.CustomerFacade; +import com.salesmanager.shop.store.controller.shoppingCart.facade.ShoppingCartFacade; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@Controller +@RequestMapping("/api/v1") +@Api(tags = { "Shopping cart api" }) +@SwaggerDefinition(tags = { + @Tag(name = "Shopping cart resource", description = "Add, remove and retrieve shopping carts") }) +public class ShoppingCartApi { + + @Inject + private ShoppingCartFacade shoppingCartFacade; + + @Inject + private com.salesmanager.shop.store.controller.shoppingCart.facade.v1.ShoppingCartFacade shoppingCartFacadev1; + + @Inject + private CustomerService customerService; + + @Autowired + private CustomerFacade customerFacadev1; + + @Autowired + private com.salesmanager.shop.store.controller.customer.facade.CustomerFacade customerFacade; + + private static final Logger LOGGER = LoggerFactory.getLogger(ShoppingCartApi.class); + + @ResponseStatus(HttpStatus.CREATED) + @PostMapping(value = "/cart") + @ApiOperation(httpMethod = "POST", value = "Add product to shopping cart when no cart exists, this will create a new cart id", notes = "No customer ID in scope. Add to cart for non authenticated users, as simple as {\"product\":1232,\"quantity\":1}", produces = "application/json", response = ReadableShoppingCart.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody ReadableShoppingCart addToCart( + @Valid @RequestBody PersistableShoppingCartItem shoppingCartItem, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + return shoppingCartFacade.addToCart(shoppingCartItem, merchantStore, language); + } + + @PutMapping(value = "/cart/{code}") + @ApiOperation(httpMethod = "PUT", value = "Add to an existing shopping cart or modify an item quantity", notes = "No customer ID in scope. Modify cart for non authenticated users, as simple as {\"product\":1232,\"quantity\":0} for instance will remove item 1234 from cart", produces = "application/json", response = ReadableShoppingCart.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ResponseEntity modifyCart( + @PathVariable String code, + @Valid @RequestBody PersistableShoppingCartItem shoppingCartItem, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletResponse response) { + + try { + ReadableShoppingCart cart = shoppingCartFacade.modifyCart(code, shoppingCartItem, merchantStore, language); + + if (cart == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + return new ResponseEntity<>(cart, HttpStatus.CREATED); + + } catch (Exception e) { + if(e instanceof ResourceNotFoundException) { + throw (ResourceNotFoundException)e; + } else { + throw new ServiceRuntimeException(e); + } + + } + } + + + @PostMapping(value = "/cart/{code}/promo/{promo}") + @ApiOperation(httpMethod = "POST", value = "Add promo / coupon to an existing cart", produces = "application/json", response = ReadableShoppingCart.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ResponseEntity modifyCart( + @PathVariable String code,//shopping cart code + @PathVariable String promo, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletResponse response) { + + try { + ReadableShoppingCart cart = shoppingCartFacade.modifyCart(code, promo, merchantStore, language); + + if (cart == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + return new ResponseEntity<>(cart, HttpStatus.CREATED); + + } catch (Exception e) { + if(e instanceof ResourceNotFoundException) { + throw (ResourceNotFoundException)e; + } else { + throw new ServiceRuntimeException(e); + } + + } + } + + + @PostMapping(value = "/cart/{code}/multi", consumes = { "application/json" }, produces = { "application/json" }) + @ApiOperation(httpMethod = "POST", value = "Add to an existing shopping cart or modify an item quantity", notes = "No customer ID in scope. Modify cart for non authenticated users, as simple as {\"product\":1232,\"quantity\":0} for instance will remove item 1234 from cart", produces = "application/json", response = ReadableShoppingCart.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ResponseEntity modifyCart( + @PathVariable String code, + @Valid @RequestBody PersistableShoppingCartItem[] shoppingCartItems, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + try { + ReadableShoppingCart cart = shoppingCartFacade.modifyCartMulti(code, Arrays.asList(shoppingCartItems), + merchantStore, language); + + return new ResponseEntity<>(cart, HttpStatus.CREATED); + + } catch (Exception e) { + if(e instanceof ResourceNotFoundException) { + throw (ResourceNotFoundException)e; + } else { + throw new ServiceRuntimeException(e); + } + + } + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = "/cart/{code}", method = RequestMethod.GET) + @ApiOperation(httpMethod = "GET", value = "Get a chopping cart by code", notes = "", produces = "application/json", response = ReadableShoppingCart.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody ReadableShoppingCart getByCode(@PathVariable String code, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, HttpServletResponse response) { + + try { + + ReadableShoppingCart cart = shoppingCartFacade.getByCode(code, merchantStore, language); + + if (cart == null) { + response.sendError(404, "No ShoppingCart found for customer code : " + code); + return null; + } + + return cart; + + } catch (Exception e) { + if(e instanceof ResourceNotFoundException) { + throw (ResourceNotFoundException)e; + } else { + throw new ServiceRuntimeException(e); + } + + } + } + + @Deprecated + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = "/customers/{id}/cart", method = RequestMethod.POST) + @ApiOperation(httpMethod = "POST", value = "Add product to a specific customer shopping cart", notes = "", produces = "application/json", response = ReadableShoppingCart.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody ReadableShoppingCart addToCart(@PathVariable Long id, + @Valid @RequestBody PersistableShoppingCartItem shoppingCartItem, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, HttpServletResponse response) { + + throw new OperationNotAllowedException("API is no more supported. Authenticate customer first then get customer cart"); + + } + + @Deprecated + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = "/auth/customer/{id}/cart", method = RequestMethod.GET) + @ApiOperation(httpMethod = "GET", value = "Get a shopping cart by customer id. Customer must be authenticated", notes = "", produces = "application/json", response = ReadableShoppingCart.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody ReadableShoppingCart getByCustomer(@PathVariable Long id, // customer + // id + @RequestParam Optional cart, // cart code + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, HttpServletRequest request, + HttpServletResponse response) { + + Principal principal = request.getUserPrincipal(); + + // lookup customer + Customer customer = customerService.getById(id); + + if (customer == null) { + throw new ResourceNotFoundException("No Customer found for id [" + id + "]"); + } + + customerFacadev1.authorize(customer, principal); + + ReadableShoppingCart readableCart = shoppingCartFacadev1.get(cart, id, merchantStore, language); + + if (readableCart == null) { + throw new ResourceNotFoundException("No cart found for customerid [" + id + "]"); + } + + return readableCart; + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = "/auth/customer/cart", method = RequestMethod.GET) + @ApiOperation(httpMethod = "GET", value = "Get a shopping cart by authenticated customer", notes = "", produces = "application/json", response = ReadableShoppingCart.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody ReadableShoppingCart getByCustomer( + @RequestParam Optional cart, // cart code + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletRequest request, + HttpServletResponse response) { + + Principal principal = request.getUserPrincipal(); + Customer customer = null; + try { + customer = customerFacade.getCustomerByUserName(principal.getName(), merchantStore); + } catch (Exception e) { + throw new ServiceRuntimeException("Exception while getting customer [ " + principal.getName() + "]"); + } + + if (customer == null) { + throw new ResourceNotFoundException("No Customer found for principal[" + principal.getName() + "]"); + } + + customerFacadev1.authorize(customer, principal); + ReadableShoppingCart readableCart = shoppingCartFacadev1.get(cart, customer.getId(), merchantStore, language); + + if (readableCart == null) { + throw new ResourceNotFoundException("No cart found for customer [" + principal.getName() + "]"); + } + + return readableCart; + + } + + @DeleteMapping(value = "/cart/{code}/product/{sku}", produces = { APPLICATION_JSON_VALUE }) + @ApiOperation(httpMethod = "DELETE", value = "Remove a product from a specific cart", notes = "If body set to true returns remaining cart in body, empty cart gives empty body. If body set to false no body ", produces = "application/json", response = ReadableShoppingCart.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en"), + @ApiImplicitParam(name = "body", dataType = "boolean", defaultValue = "false"), }) + public ResponseEntity deleteCartItem(@PathVariable("code") String cartCode, + @PathVariable("sku") String sku, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, + @RequestParam(defaultValue = "false") boolean body) throws Exception { + + ReadableShoppingCart updatedCart = shoppingCartFacade.removeShoppingCartItem(cartCode, sku, merchantStore, + language, body); + if (body) { + return new ResponseEntity<>(updatedCart, HttpStatus.OK); + } + return new ResponseEntity<>(updatedCart, HttpStatus.NO_CONTENT); + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/store/MerchantStoreApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/store/MerchantStoreApi.java new file mode 100755 index 0000000000..5bf5934139 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/store/MerchantStoreApi.java @@ -0,0 +1,377 @@ +package com.salesmanager.shop.store.api.v1.store; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.Principal; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import com.google.common.collect.ImmutableMap; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.InputContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.merchant.MerchantStoreCriteria; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.model.entity.EntityExists; +import com.salesmanager.shop.model.store.PersistableBrand; +import com.salesmanager.shop.model.store.PersistableMerchantStore; +import com.salesmanager.shop.model.store.ReadableBrand; +import com.salesmanager.shop.model.store.ReadableMerchantStore; +import com.salesmanager.shop.model.store.ReadableMerchantStoreList; +import com.salesmanager.shop.store.api.exception.RestApiException; +import com.salesmanager.shop.store.api.exception.UnauthorizedException; +import com.salesmanager.shop.store.controller.store.facade.StoreFacade; +import com.salesmanager.shop.store.controller.user.facade.UserFacade; +import com.salesmanager.shop.utils.ServiceRequestCriteriaBuilderUtils; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@RestController +@RequestMapping("/api/v1") +@Api(tags = { "Merchant and store management resource (Merchant - Store Management Api)" }) +@SwaggerDefinition(tags = { + @Tag(name = "Merchant and store management", description = "Edit merchants (retailers) and stores") }) +public class MerchantStoreApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(MerchantStoreApi.class); + + private static final Map MAPPING_FIELDS = ImmutableMap.builder() + .put("name", "name").put("readableAudit.user", "auditSection.modifiedBy").build(); + + @Inject + private StoreFacade storeFacade; + + @Inject + private UserFacade userFacade; + + @GetMapping(value = { "/store/{code}" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get merchant store", notes = "", response = ReadableMerchantStore.class) + public ReadableMerchantStore store(@PathVariable String code, + @RequestParam(value = "lang", required = false) String lang) { + //return storeFacade.getByCode(code, lang); + ReadableMerchantStore readable = storeFacade.getByCode(code, lang); + return readable; + } + + @GetMapping(value = { "/private/store/{code}" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get merchant store full details", notes = "", response = ReadableMerchantStore.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableMerchantStore storeFull( + @PathVariable String code, + @ApiIgnore Language language) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of("SUPERADMIN", "ADMIN_RETAILER").collect(Collectors.toList())); + return storeFacade.getFullByCode(code, language); + } + + @GetMapping(value = { "/private/merchant/{code}/stores" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get retailer child stores", notes = "Merchant (retailer) can have multiple stores", response = ReadableMerchantStore.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableMerchantStoreList list(@PathVariable String code, @ApiIgnore Language language, + @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, + @RequestParam(value = "count", required = false, defaultValue = "10") Integer count) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of("SUPERADMIN", "ADMIN_RETAILER").collect(Collectors.toList())); + + //ADMIN_RETAILER only see pertaining stores + + + return storeFacade.getChildStores(language, code, page, count); + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/stores" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get list of stores. Returns all retailers and stores. If superadmin everything is returned, else only retailer and child stores.", notes = "", response = ReadableMerchantStore.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableMerchantStoreList get( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, + @RequestParam(value = "count", required = false, defaultValue = "10") Integer count, + HttpServletRequest request) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + // requires superadmin, admin and admin retail to see all + userFacade.authorizedGroup(authenticatedUser, + Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, Constants.GROUP_ADMIN_RETAIL) + .collect(Collectors.toList())); + + MerchantStoreCriteria criteria = createMerchantStoreCriteria(request); + + if (userFacade.userInRoles(authenticatedUser, Arrays.asList(Constants.GROUP_SUPERADMIN))) { + criteria.setStoreCode(null); + } else { + criteria.setStoreCode(merchantStore.getCode()); + } + + //return storeFacade.findAll(criteria, language, page, count); + ReadableMerchantStoreList readable = storeFacade.findAll(criteria, language, page, count); + return readable; + } + + + + /** + * List of store names + * @param merchantStore + * @param request + * @return + */ + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/stores/names" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get list of store names. Returns all retailers and stores", notes = "", response = ReadableMerchantStore.class) + public List list( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, + @RequestParam(value = "count", required = false, defaultValue = "10") Integer count, + HttpServletRequest request + ) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + // requires superadmin, admin and admin retail to see all + userFacade.authorizedGroup(authenticatedUser, + Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, Constants.GROUP_ADMIN_RETAIL) + .collect(Collectors.toList())); + + MerchantStoreCriteria criteria = createMerchantStoreCriteria(request); + + if (userFacade.userInRoles(authenticatedUser, Arrays.asList(Constants.GROUP_SUPERADMIN))) { + criteria.setStoreCode(null); + } else { + criteria.setStoreCode(merchantStore.getCode()); + } + + ReadableMerchantStoreList list = storeFacade.findAll(criteria, language, page, count); + return list.getData(); + + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/store/languages" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get list of store supported languages.", notes = "", response = ReadableMerchantStore.class) + public List supportedLanguages( + @ApiIgnore MerchantStore merchantStore, + HttpServletRequest request) { + + return storeFacade.supportedLanguages(merchantStore); + } + + @ResponseStatus(HttpStatus.OK) + @PostMapping(value = { "/private/store" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "POST", value = "Creates a new store", notes = "", response = ReadableMerchantStore.class) + public void create(@Valid @RequestBody PersistableMerchantStore store) { + + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of("SUPERADMIN", "ADMIN_RETAILER").collect(Collectors.toList())); + + + storeFacade.create(store); + } + + @ResponseStatus(HttpStatus.OK) + @PutMapping(value = { "/private/store/{code}" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "PUT", value = "Updates a store", notes = "", response = ReadableMerchantStore.class) + public void update(@PathVariable String code, @Valid @RequestBody PersistableMerchantStore store, + HttpServletRequest request) { + + String userName = getUserFromRequest(request); + validateUserPermission(userName, code); + store.setCode(code); + storeFacade.update(store); + } + + private String getUserFromRequest(HttpServletRequest request) { + // user doing action must be attached to the store being modified + Principal principal = request.getUserPrincipal(); + return principal.getName(); + } + + private void validateUserPermission(String userName, String code) { + // TODO reviewed Spring Security should be used + if (!userFacade.authorizedStore(userName, code)) { + throw new UnauthorizedException("User " + userName + " not authorized"); + } + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/store/{code}/marketing" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get store branding and marketing details", notes = "", response = ReadableBrand.class) + public ReadableBrand getStoreMarketing(@PathVariable String code, HttpServletRequest request) { + String userName = getUserFromRequest(request); + validateUserPermission(userName, code); + return storeFacade.getBrand(code); + } + + /** + * List child stores + * + * @param code + * @param request + * @return + */ + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/merchant/{code}/children" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get child stores", notes = "", response = List.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableMerchantStoreList children(@PathVariable String code, @ApiIgnore Language language, + @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, + @RequestParam(value = "count", required = false, defaultValue = "10") Integer count, + HttpServletRequest request) { + + String userName = getUserFromRequest(request); + validateUserPermission(userName, code); + return storeFacade.getChildStores(language, code, page, count); + + } + + @Deprecated + @ResponseStatus(HttpStatus.CREATED) + @PostMapping(value = { "/private/store/{code}/marketing" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "POST", value = "Create or save store branding and marketing details", notes = "", response = ReadableBrand.class) + public void saveStoreMarketing(@PathVariable String code, @RequestBody PersistableBrand brand, + HttpServletRequest request) { + String userName = getUserFromRequest(request); + validateUserPermission(userName, code); + storeFacade.createBrand(code, brand); + } + + @ResponseStatus(HttpStatus.CREATED) + @PostMapping(value = { "/private/store/{code}/marketing/logo" }) + @ApiOperation(httpMethod = "POST", value = "Add store logo", notes = "") + public void addLogo(@PathVariable String code, @RequestParam("file") MultipartFile uploadfile, + HttpServletRequest request) { + + // user doing action must be attached to the store being modified + String userName = getUserFromRequest(request); + + validateUserPermission(userName, code); + + if (uploadfile.isEmpty()) { + throw new RestApiException("Upload file is empty"); + } + + InputContentFile cmsContentImage = createInputContentFile(uploadfile); + storeFacade.addStoreLogo(code, cmsContentImage); + } + + private InputContentFile createInputContentFile(MultipartFile image) { + + InputContentFile cmsContentImage = null; + + try { + + InputStream input = new ByteArrayInputStream(image.getBytes()); + cmsContentImage = new InputContentFile(); + cmsContentImage.setFileName(image.getOriginalFilename()); + cmsContentImage.setMimeType(image.getContentType()); + cmsContentImage.setFileContentType(FileContentType.LOGO); + cmsContentImage.setFile(input); + + } catch (IOException ioe) { + throw new RestApiException(ioe); + } + + return cmsContentImage; + } + + @ResponseStatus(HttpStatus.OK) + @DeleteMapping(value = { "/private/store/{code}/marketing/logo" }) + @ApiOperation(httpMethod = "DELETE", value = "Delete store logo", notes = "", response = Void.class) + public void deleteStoreLogo(@PathVariable String code, HttpServletRequest request) { + + // user doing action must be attached to the store being modified + String userName = getUserFromRequest(request); + validateUserPermission(userName, code); + + // delete store logo + storeFacade.deleteLogo(code); + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/store/unique","/private/store/unique" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Check if store code already exists", notes = "", response = EntityExists.class) + public ResponseEntity exists(@RequestParam(value = "code") String code) { + boolean isStoreExist = storeFacade.existByCode(code); + return new ResponseEntity(new EntityExists(isStoreExist), HttpStatus.OK); + } + + + + @ResponseStatus(HttpStatus.OK) + @DeleteMapping(value = { "/private/store/{code}" }) + @ApiOperation(httpMethod = "DELETE", value = "Deletes a store", notes = "", response = Void.class) + public void delete(@PathVariable String code, HttpServletRequest request) { + String userName = getUserFromRequest(request); + validateUserPermission(userName, code); + storeFacade.delete(code); + } + + + private MerchantStoreCriteria createMerchantStoreCriteria(HttpServletRequest request) { + try { + return (MerchantStoreCriteria)ServiceRequestCriteriaBuilderUtils.buildRequestCriterias(new MerchantStoreCriteria(), MAPPING_FIELDS, + request); + } catch (Exception e) { + throw new RestApiException("Error while binding request parameters"); + } + + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/system/ContactApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/system/ContactApi.java new file mode 100755 index 0000000000..22370d6715 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/system/ContactApi.java @@ -0,0 +1,62 @@ +package com.salesmanager.shop.store.api.v1.system; + +import java.util.Locale; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.shop.ContactForm; +import com.salesmanager.shop.utils.EmailTemplatesUtils; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@RestController +@RequestMapping("/api/v1") +@Api(tags = {"Contact form api"}) +@SwaggerDefinition(tags = { + @Tag(name = "Contact store resource", description = "Contact form") +}) +public class ContactApi { + + + @Inject private LanguageService languageService; + + @Inject private EmailTemplatesUtils emailTemplatesUtils; + + @PostMapping("/contact") + @ApiOperation( + httpMethod = "POST", + value = "Sends an email contact us to store owner", + notes = "", + produces = "application/json") + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public ResponseEntity contact( + @Valid @RequestBody ContactForm contact, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletRequest request) { + Locale locale = languageService.toLocale(language, merchantStore); + emailTemplatesUtils.sendContactEmail(contact, merchantStore, locale, request.getContextPath()); + return new ResponseEntity(HttpStatus.OK); + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/system/ModulesApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/system/ModulesApi.java new file mode 100755 index 0000000000..b07bece5b4 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/system/ModulesApi.java @@ -0,0 +1,57 @@ +package com.salesmanager.shop.store.api.v1.system; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/v1/system") +public class ModulesApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(ModulesApi.class); + + + /** + * Creates or updates a configuration module. A JSON has to be created on the client side which represents + * an object that will create a new module (payment, shipping ...) which can be used and configured from + * the administration tool. Here is an example of configuration accepted + * + * { + "module": "PAYMENT", + "code": "paypal-express-checkout", + "type":"paypal", + "version":"104.0", + "regions": ["*"], + "image":"icon-paypal.png", + "configuration":[{"env":"TEST","scheme":"","host":"","port":"","uri":"","config1":"https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token="},{"env":"PROD","scheme":"","host":"","port":"","uri":"","config1":"https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token="}] + } + * + * see : shopizer/sm-core/src/main/resources/reference/integrationmodules.json for more samples + * @param json + * @param request + * @param response + * @throws Exception + */ +/* @PostMapping(value = "/module", consumes = MediaType.TEXT_PLAIN) + @ApiOperation( + httpMethod = "POST", + value = "Creates a new module", + notes = "", + produces = "application/json") + public ReadableEntity createModule(@RequestBody String json, HttpServletRequest request) { + + LOGGER.debug("Creating an integration module : " + json); + + try { + moduleConfigurationService.createOrUpdateModule(json); + } catch (ServiceException e) { + // TODO Auto-generated catch block + throw new RestApiException(e); + } + + return new ReadableEntity(); + + }*/ + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/system/OptinApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/system/OptinApi.java new file mode 100755 index 0000000000..92e366f8ac --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/system/OptinApi.java @@ -0,0 +1,51 @@ +package com.salesmanager.shop.store.api.v1.system; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.system.PersistableOptin; +import com.salesmanager.shop.model.system.ReadableOptin; +import com.salesmanager.shop.store.controller.optin.OptinFacade; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import springfox.documentation.annotations.ApiIgnore; + +/** Optin a customer to events such s newsletter */ +@RestController +@RequestMapping("/api/v1") +public class OptinApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(OptinApi.class); + + @Inject private OptinFacade optinFacade; + + + /** Create new optin */ + @PostMapping("/private/optin") + @ApiOperation( + httpMethod = "POST", + value = "Creates an optin event type definition", + notes = "", + produces = "application/json") + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public ReadableOptin create( + @Valid @RequestBody PersistableOptin optin, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletRequest request) { + LOGGER.debug("[" + request.getUserPrincipal().getName() + "] creating optin [" + optin.getCode() + "]"); + return optinFacade.create(optin, merchantStore, language); + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/system/PublicConfigsApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/system/PublicConfigsApi.java new file mode 100755 index 0000000000..0adf11a7ed --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/system/PublicConfigsApi.java @@ -0,0 +1,51 @@ +package com.salesmanager.shop.store.api.v1.system; + +import javax.inject.Inject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.system.Configs; +import com.salesmanager.shop.store.controller.store.facade.StoreFacade; +import com.salesmanager.shop.store.controller.system.MerchantConfigurationFacade; +import com.salesmanager.shop.utils.LanguageUtils; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import springfox.documentation.annotations.ApiIgnore; + +@RestController +@RequestMapping("/api/v1") +public class PublicConfigsApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(PublicConfigsApi.class); + + @Inject private StoreFacade storeFacade; + + @Inject private LanguageUtils languageUtils; + + @Inject private MerchantConfigurationFacade configurationFacade; + + /** + * Get public set of merchant configuration --- allow online purchase --- social links + * + * @return + */ + @GetMapping("/config") + @ApiOperation( + httpMethod = "GET", + value = "Get public configuration for a given merchant store", + notes = "", + produces = "application/json", + response = Configs.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public Configs getConfig(@ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + return configurationFacade.getMerchantConfig(merchantStore, language); + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/system/SearchToolsApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/system/SearchToolsApi.java new file mode 100755 index 0000000000..7d218955cf --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/system/SearchToolsApi.java @@ -0,0 +1,86 @@ +package com.salesmanager.shop.store.api.v1.system; + +import java.security.Principal; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.model.user.ReadableUser; +import com.salesmanager.shop.store.api.exception.RestApiException; +import com.salesmanager.shop.store.api.exception.UnauthorizedException; +import com.salesmanager.shop.store.controller.search.facade.SearchFacade; +import com.salesmanager.shop.store.controller.user.facade.UserFacade; + +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import springfox.documentation.annotations.ApiIgnore; + +/** + * Searching and indexing products + * + * @author c.samson + * + */ + +@Controller +@RequestMapping("/api/v1") +public class SearchToolsApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(SearchToolsApi.class); + + @Inject + private SearchFacade searchFacade; + + @Inject + private UserFacade userFacade; + + @PostMapping("/private/system/search/index") + @ApiOperation(httpMethod = "POST", value = "Indexes all products", notes = "", produces = "application/json") + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ResponseEntity contact(@ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, HttpServletRequest request) { + + // superadmin, admin and admin_catalogue + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + Principal principal = request.getUserPrincipal(); + String userName = principal.getName(); + ReadableUser user = userFacade.findByUserName(userName, null, language); + + if(user== null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL) + .collect(Collectors.toList())); + + if(!user.getMerchant().equals(merchantStore.getCode())) { + throw new UnauthorizedException(); + } + try { + searchFacade.indexAllData(merchantStore); + } catch (Exception e) { + throw new RestApiException("Exception while indexing store data", e); + } + return new ResponseEntity(HttpStatus.CREATED); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/tax/TaxClassApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/tax/TaxClassApi.java new file mode 100644 index 0000000000..629cae22c8 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/tax/TaxClassApi.java @@ -0,0 +1,122 @@ +package com.salesmanager.shop.store.api.v1.tax; + +import javax.validation.Valid; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.entity.Entity; +import com.salesmanager.shop.model.entity.EntityExists; +import com.salesmanager.shop.model.entity.ReadableEntityList; +import com.salesmanager.shop.model.tax.PersistableTaxClass; +import com.salesmanager.shop.model.tax.ReadableTaxClass; +import com.salesmanager.shop.store.controller.tax.facade.TaxFacade; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +/** + * Tax class management + * + * @author carlsamson + * + */ + +@RestController +@RequestMapping(value = "/api/v1") +@Api(tags = { "Tax class management resource (Tax class management Api)" }) +@SwaggerDefinition(tags = { @Tag(name = "Tax class management resource", description = "Manage tax classes") }) +public class TaxClassApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(TaxClassApi.class); + + @Autowired + private TaxFacade taxFacade; + + /** Create new tax class for a given MerchantStore */ + @PostMapping("/private/tax/class") + @ApiOperation(httpMethod = "POST", value = "Creates a taxClass", notes = "Requires administration access", produces = "application/json", response = Entity.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public Entity create(@ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, + @Valid @RequestBody PersistableTaxClass taxClass) { + + return taxFacade.createTaxClass(taxClass, merchantStore, language); + + } + + @GetMapping(value = "/private/tax/class/unique", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Verify if taxClass is unique", notes = "", produces = "application/json", response = ResponseEntity.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ResponseEntity exists(@RequestParam String code, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + boolean exists = taxFacade.existsTaxClass(code, merchantStore, language); + return new ResponseEntity(new EntityExists(exists), HttpStatus.OK); + + } + + /** Update tax class for a given MerchantStore */ + @PutMapping("/private/tax/class/{id}") + @ApiOperation(httpMethod = "PUT", value = "Updates a taxClass", notes = "Requires administration access", produces = "application/json", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public void update(@ApiIgnore MerchantStore merchantStore, @PathVariable Long id, @ApiIgnore Language language, + @Valid @RequestBody PersistableTaxClass taxClass) { + + taxClass.setId(id); + taxFacade.updateTaxClass(id, taxClass, merchantStore, language); + + } + + @GetMapping(value = "/private/tax/class", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "List taxClasses by store", notes = "", produces = "application/json", response = ReadableEntityList.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableEntityList list(@RequestParam(name = "count", defaultValue = "10") int count, + @RequestParam(name = "page", defaultValue = "0") int page, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + return taxFacade.taxClasses(merchantStore, language); + + } + + @GetMapping("/private/tax/class/{code}") + @ApiOperation(httpMethod = "GET", value = "Get a taxClass by code", notes = "Requires administration access", produces = "application/json", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public ReadableTaxClass get(@ApiIgnore MerchantStore merchantStore, @PathVariable String code, @ApiIgnore Language language) { + + return taxFacade.taxClass(code, merchantStore, language); + + } + + @DeleteMapping(value = "/private/tax/class/{id}", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "DELETE", value = "Delete tax class", notes = "", produces = "application/json", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void delete(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + taxFacade.deleteTaxClass(id, merchantStore, language); + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/tax/TaxRatesApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/tax/TaxRatesApi.java new file mode 100644 index 0000000000..c178a6e54a --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/tax/TaxRatesApi.java @@ -0,0 +1,122 @@ +package com.salesmanager.shop.store.api.v1.tax; + +import javax.validation.Valid; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.entity.Entity; +import com.salesmanager.shop.model.entity.EntityExists; +import com.salesmanager.shop.model.entity.ReadableEntityList; +import com.salesmanager.shop.model.tax.PersistableTaxRate; +import com.salesmanager.shop.model.tax.ReadableTaxRate; +import com.salesmanager.shop.store.controller.tax.facade.TaxFacade; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +/** + * Tax class management + * + * @author carlsamson + * + */ + +@RestController +@RequestMapping(value = "/api/v1") +@Api(tags = { "Tax rates management resource (Tax rates management Api)" }) +@SwaggerDefinition(tags = { @Tag(name = "Tax rates management resource", description = "Manage tax rates") }) +public class TaxRatesApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(TaxRatesApi.class); + + @Autowired + private TaxFacade taxFacade; + + /** Create new tax rate for a given MerchantStore */ + @PostMapping("/private/tax/rate") + @ApiOperation(httpMethod = "POST", value = "Creates a taxRate", notes = "Requires administration access", produces = "application/json", response = Entity.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public Entity create(@ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, + @Valid @RequestBody PersistableTaxRate taxRate) { + + return taxFacade.createTaxRate(taxRate, merchantStore, language); + + } + + @GetMapping(value = "/private/tax/rate/unique", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Verify if taxRate is unique", notes = "", produces = "application/json", response = ResponseEntity.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ResponseEntity exists(@RequestParam String code, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + boolean exists = taxFacade.existsTaxRate(code, merchantStore, language); + return new ResponseEntity(new EntityExists(exists), HttpStatus.OK); + + } + + /** Update tax rate for a given MerchantStore */ + @PutMapping("/private/tax/rate/{id}") + @ApiOperation(httpMethod = "PUT", value = "Updates a taxRate", notes = "Requires administration access", produces = "application/json", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public void update(@ApiIgnore MerchantStore merchantStore, @PathVariable Long id, @ApiIgnore Language language, + @Valid @RequestBody PersistableTaxRate taxRate) { + + taxRate.setId(id); + taxFacade.updateTaxRate(id, taxRate, merchantStore, language); + + } + + @GetMapping(value = "/private/tax/rates", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "List taxRates by store", notes = "", produces = "application/json", response = ReadableEntityList.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableEntityList list(@RequestParam(name = "count", defaultValue = "10") int count, + @RequestParam(name = "page", defaultValue = "0") int page, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + return taxFacade.taxRates(merchantStore, language); + + } + + @GetMapping("/private/tax/rate/{id}") + @ApiOperation(httpMethod = "GET", value = "Get a taxRate by code", notes = "Requires administration access", produces = "application/json", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public ReadableTaxRate get(@ApiIgnore MerchantStore merchantStore, @PathVariable Long id, @ApiIgnore Language language) { + + return taxFacade.taxRate(id, merchantStore, language); + + } + + @DeleteMapping(value = "/private/tax/rate/{id}", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "DELETE", value = "Delete tax rate", notes = "", produces = "application/json", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void delete(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + taxFacade.deleteTaxRate(id, merchantStore, language); + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/user/AuthenticateUserApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/user/AuthenticateUserApi.java new file mode 100755 index 0000000000..98c9e3430f --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/user/AuthenticateUserApi.java @@ -0,0 +1,128 @@ +package com.salesmanager.shop.store.api.v1.user; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +import org.apache.http.auth.AuthenticationException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import com.salesmanager.shop.store.security.AuthenticationRequest; +import com.salesmanager.shop.store.security.AuthenticationResponse; +import com.salesmanager.shop.store.security.JWTTokenUtil; +import com.salesmanager.shop.store.security.user.JWTUser; + +import io.swagger.annotations.Api; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; + +/** + * Authenticates a User (Administration purpose) + * @author c.samson + * + */ +@Controller +@RequestMapping("/api/v1") +@Api(tags = { "User authentication Api" }) +@SwaggerDefinition(tags = { + @Tag(name = "User authentication resource", description = "Login for administrator users") }) +public class AuthenticateUserApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticateUserApi.class); + + @Value("${authToken.header}") + private String tokenHeader; + + @Inject + private AuthenticationManager jwtAdminAuthenticationManager; + + @Inject + private UserDetailsService jwtAdminDetailsService; + + @Inject + private JWTTokenUtil jwtTokenUtil; + + /** + * Authenticate a user using username & password + * @param authenticationRequest + * @param device + * @return + * @throws AuthenticationException + */ + @RequestMapping(value = "/private/login", method = RequestMethod.POST) + public ResponseEntity authenticate(@RequestBody @Valid AuthenticationRequest authenticationRequest) throws AuthenticationException { + + //TODO SET STORE in flow + // Perform the security + Authentication authentication = null; + try { + + + //to be used when username and password are set + authentication = jwtAdminAuthenticationManager.authenticate( + new UsernamePasswordAuthenticationToken( + authenticationRequest.getUsername(), + authenticationRequest.getPassword() + ) + ); + + } catch(Exception e) { + if(e instanceof BadCredentialsException) { + return new ResponseEntity<>("{\"message\":\"Bad credentials\"}",HttpStatus.UNAUTHORIZED); + } + LOGGER.error("Error during authentication " + e.getMessage()); + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + if(authentication == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + SecurityContextHolder.getContext().setAuthentication(authentication); + + // Reload password post-security so we can generate token + final JWTUser userDetails = (JWTUser)jwtAdminDetailsService.loadUserByUsername(authenticationRequest.getUsername()); + + final String token = jwtTokenUtil.generateToken(userDetails); + + // Return the token + return ResponseEntity.ok(new AuthenticationResponse(userDetails.getId(),token)); + + } + + @RequestMapping(value = "/auth/refresh", method = RequestMethod.GET) + public ResponseEntity refreshAndGetAuthenticationToken(HttpServletRequest request) { + String token = request.getHeader(tokenHeader); + + if(token != null && token.contains("Bearer")) { + token = token.substring("Bearer ".length(),token.length()); + } + + String username = jwtTokenUtil.getUsernameFromToken(token); + JWTUser user = (JWTUser) jwtAdminDetailsService.loadUserByUsername(username); + + if (jwtTokenUtil.canTokenBeRefreshedWithGrace(token, user.getLastPasswordResetDate())) { + String refreshedToken = jwtTokenUtil.refreshToken(token); + return ResponseEntity.ok(new AuthenticationResponse(user.getId(),refreshedToken)); + } else { + return ResponseEntity.badRequest().body(null); + } + } + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/user/ResetUserPasswordApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/user/ResetUserPasswordApi.java new file mode 100644 index 0000000000..4f57e6ff83 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/user/ResetUserPasswordApi.java @@ -0,0 +1,133 @@ +package com.salesmanager.shop.store.api.v1.user; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.user.ReadableUser; +import com.salesmanager.shop.store.api.exception.RestApiException; +import com.salesmanager.shop.store.controller.user.facade.UserFacade; +import com.salesmanager.shop.store.security.PasswordRequest; +import com.salesmanager.shop.store.security.ResetPasswordRequest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@RestController +@RequestMapping(value = "/api/v1") +@Api(tags = { "User password reset resource (User password reset Api)" }) +@SwaggerDefinition(tags = { @Tag(name = "User password reset resource", description = "User password reset") }) +public class ResetUserPasswordApi { + + + private static final Logger LOGGER = LoggerFactory.getLogger(ResetUserPasswordApi.class); + + + + @Inject + private UserFacade userFacade; + + /** + * Request a reset password token + * @param merchantStore + * @param language + * @param user + * @param request + */ + @ResponseStatus(HttpStatus.OK) + @PostMapping(value = { "/user/password/reset/request" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "POST", value = "Launch user password reset flow", notes = "", response = ReadableUser.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void passwordResetRequest( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + @Valid @RequestBody ResetPasswordRequest user, HttpServletRequest request) { + + + userFacade.requestPasswordReset(user.getUsername(), user.getReturnUrl(), merchantStore, language); + + } + + /** + * Verify a password token + * @param store + * @param token + * @param merchantStore + * @param language + * @param request + */ + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/user/{store}/reset/{token}" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Validate user password reset token", notes = "", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void passwordResetVerify(@PathVariable String store, @PathVariable String token, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, HttpServletRequest request) { + + /** + * Receives reset token Needs to validate if user found from token Needs + * to validate if token has expired + * + * If no problem void is returned otherwise throw OperationNotAllowed + * All of this in UserFacade + */ + + userFacade.verifyPasswordRequestToken(token, store); + + } + + /** + * Change password + * @param passwordRequest + * @param store + * @param token + * @param merchantStore + * @param language + * @param request + */ + @PostMapping(value = "/user/{store}/password/{token}", produces = { + "application/json" }) + @ApiOperation(httpMethod = "POST", value = "Change user password", response = Void.class) + public void changePassword( + @RequestBody @Valid PasswordRequest passwordRequest, + @PathVariable String store, + @PathVariable String token, @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, + HttpServletRequest request) { + + // validate password + if (StringUtils.isBlank(passwordRequest.getPassword()) + || StringUtils.isBlank(passwordRequest.getRepeatPassword())) { + throw new RestApiException("400", "Password don't match"); + } + + if (!passwordRequest.getPassword().equals(passwordRequest.getRepeatPassword())) { + throw new RestApiException("400", "Password don't match"); + } + + userFacade.resetPassword(passwordRequest.getPassword(), token, store); + + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/user/UserApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/user/UserApi.java new file mode 100755 index 0000000000..87e3b675c4 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v1/user/UserApi.java @@ -0,0 +1,284 @@ +package com.salesmanager.shop.store.api.v1.user; + +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import java.security.Principal; +import java.util.Arrays; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.user.UserCriteria; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.model.entity.EntityExists; +import com.salesmanager.shop.model.entity.UniqueEntity; +import com.salesmanager.shop.model.user.PersistableUser; +import com.salesmanager.shop.model.user.ReadableUser; +import com.salesmanager.shop.model.user.ReadableUserList; +import com.salesmanager.shop.model.user.UserPassword; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.UnauthorizedException; +import com.salesmanager.shop.store.controller.user.facade.UserFacade; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +/** Api for managing admin users */ +@RestController +@RequestMapping(value = "/api/v1") +@Api(tags = { "User management resource (User Management Api)" }) +@SwaggerDefinition(tags = { @Tag(name = "User management resource", description = "Manage administration users") }) +public class UserApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(UserApi.class); + + + @Inject + private UserFacade userFacade; + + /** + * Get userName by merchant code and userName + * + * @param storeCode + * @param name + * @param request + * @return + */ + @ResponseStatus(HttpStatus.OK) + @GetMapping({ "/private/users/{id}" }) + @ApiOperation(httpMethod = "GET", value = "Get a specific user profile by user id", notes = "", produces = MediaType.APPLICATION_JSON_VALUE, response = ReadableUser.class) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Success", responseContainer = "User", response = ReadableUser.class), + @ApiResponse(code = 400, message = "Error while getting User"), + @ApiResponse(code = 401, message = "Login required") }) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public ReadableUser get(@ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, @PathVariable Long id, + HttpServletRequest request) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + // only admin and superadmin allowed + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + return userFacade.findById(id, merchantStore, language); + } + + /** + * Creates a new user + * + * @param store + * @param user + * @return + */ + @ResponseStatus(HttpStatus.OK) + @PostMapping(value = { "/private/user/" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "POST", value = "Creates a new user", notes = "", response = ReadableUser.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableUser create( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + @Valid @RequestBody PersistableUser user, HttpServletRequest request) { + /** Must be superadmin or admin */ + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + // only admin and superadmin allowed + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + /** if user is admin, user must be in that store */ + if (!userFacade.userInRoles(authenticatedUser, Arrays.asList(Constants.GROUP_SUPERADMIN))) { + if (!userFacade.authorizedStore(authenticatedUser, merchantStore.getCode())) { + throw new UnauthorizedException("Operation unauthorized for user [" + authenticatedUser + + "] and store [" + merchantStore.getCode() + "]"); + } + } + + return userFacade.create(user, merchantStore); + } + + @ResponseStatus(HttpStatus.OK) + @PutMapping(value = { "/private/user/{id}" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + @ApiOperation(httpMethod = "PUT", value = "Updates a user", notes = "", response = ReadableUser.class) + public ReadableUser update(@Valid @RequestBody PersistableUser user, @PathVariable Long id, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language + + ) { + + String authenticatedUser = userFacade.authenticatedUser();// requires + // user + // doing + // action + + userFacade.authorizedGroups(authenticatedUser, user); + + return userFacade.update(id, authenticatedUser, merchantStore, user); + } + + @ResponseStatus(HttpStatus.OK) + @PatchMapping(value = { "/private/user/{id}/password" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "PATCH", value = "Updates a user password", notes = "", response = Void.class) + public void password(@Valid @RequestBody UserPassword password, @PathVariable Long id) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + userFacade.changePassword(id, authenticatedUser, password); + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/users" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "GET", value = "Get list of user", notes = "", response = ReadableUserList.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableUserList list( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, + @RequestParam(value = "count", required = false, defaultValue = "20") Integer count, + @RequestParam(value = "emailAddress", required = false) String emailAddress) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + UserCriteria criteria = new UserCriteria(); + if(!StringUtils.isBlank(emailAddress)) { + criteria.setAdminEmail(emailAddress); + } + + criteria.setStoreCode(merchantStore.getCode()); + + if (!userFacade.userInRoles(authenticatedUser, Arrays.asList(Constants.GROUP_SUPERADMIN))) { + if (!userFacade.authorizedStore(authenticatedUser, merchantStore.getCode())) { + throw new UnauthorizedException("Operation unauthorized for user [" + authenticatedUser + + "] and store [" + merchantStore + "]"); + } + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + return userFacade.listByCriteria(criteria, page, count, language); + } + + @PatchMapping(value = "/private/user/{id}/enabled", produces = { APPLICATION_JSON_VALUE }) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT") }) + public void updateEnabled( + @PathVariable Long id, + @Valid @RequestBody PersistableUser user, + @ApiIgnore MerchantStore merchantStore + ) { + + // superadmin, admin and retail_admin + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + user.setId(id); + userFacade.updateEnabled(merchantStore, user); + } + + @ResponseStatus(HttpStatus.OK) + @DeleteMapping(value = { "/private/user/{id}" }) + @ApiOperation(httpMethod = "DELETE", value = "Deletes a user", notes = "", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public void delete(@ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, @PathVariable Long id, + HttpServletRequest request) { + + /** Must be superadmin or admin */ + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + if (!userFacade.userInRoles(authenticatedUser, Arrays.asList(Constants.GROUP_SUPERADMIN))) { + userFacade.authorizedStore(authenticatedUser, merchantStore.getCode()); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + userFacade.delete(id, merchantStore.getCode()); + } + + @ResponseStatus(HttpStatus.OK) + @PostMapping(value = { "/private/user/unique" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(httpMethod = "POST", value = "Check if username already exists", notes = "", response = EntityExists.class) + public ResponseEntity exists(@ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, + @RequestBody UniqueEntity userName) { + + boolean isUserExist = true;// default user exist + try { + // will throw an exception if not fount + userFacade.findByUserName(userName.getUnique(), userName.getMerchant(), language); + + } catch (ResourceNotFoundException e) { + isUserExist = false; + } + return new ResponseEntity(new EntityExists(isUserExist), HttpStatus.OK); + } + + /** + * Get logged in customer profile + * + * @param merchantStore + * @param language + * @param request + * @return + */ + @GetMapping("/private/user/profile") + @ApiImplicitParams({ @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public ReadableUser getAuthUser(@ApiIgnore Language language, HttpServletRequest request) { + Principal principal = request.getUserPrincipal(); + String userName = principal.getName(); + ReadableUser user = userFacade.findByUserName(userName, null, language); + + if (!user.isActive()) { + throw new UnauthorizedException("User " + userName + " not not active"); + } + + return user; + + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v2/product/ProductApiV2.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v2/product/ProductApiV2.java new file mode 100755 index 0000000000..dd38f5f5c9 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v2/product/ProductApiV2.java @@ -0,0 +1,295 @@ +package com.salesmanager.shop.store.api.v2.product; + +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +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.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +import com.salesmanager.core.model.catalog.product.ProductCriteria; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.LightPersistableProduct; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.model.catalog.product.ReadableProductList; +import com.salesmanager.shop.model.catalog.product.product.PersistableProduct; +import com.salesmanager.shop.model.catalog.product.product.definition.PersistableProductDefinition; +import com.salesmanager.shop.model.catalog.product.product.definition.ReadableProductDefinition; +import com.salesmanager.shop.model.entity.Entity; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.product.facade.ProductCommonFacade; +import com.salesmanager.shop.store.controller.product.facade.ProductDefinitionFacade; +import com.salesmanager.shop.store.controller.product.facade.ProductFacade; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +/** + * API to create, read, update and delete a Product API. + * + * @author Carl Samson + */ +@Controller +@RequestMapping("/api/v2") +@Api(tags = { + "Product display and management resource (Product display and Management Api such as adding a product to category. Serves api v1 and v2 with backward compatibility)" }) +@SwaggerDefinition(tags = { + @Tag(name = "Product management resource, add product to category", description = "View product, Add product, edit product and delete product") }) +public class ProductApiV2 { + + + @Autowired + private ProductDefinitionFacade productDefinitionFacade; + + @Autowired + private ProductFacade productFacadeV2; + + @Autowired + private ProductCommonFacade productCommonFacade; + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductApiV2.class); + + + /** + * Create product inventory with variants, quantity and prices + * @param product + * @param merchantStore + * @param language + * @return + */ + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = { "/private/product/inventory" }, + method = RequestMethod.POST) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody Entity create( + @Valid @RequestBody PersistableProduct product, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + Long id = productCommonFacade.saveProduct(merchantStore, product, language); + Entity returnEntity = new Entity(); + returnEntity.setId(id); + return returnEntity; + + } + + + /** + * ------------ V2 + * + * --- product definition + */ + + @ResponseStatus(HttpStatus.CREATED) + @PostMapping(value = { "/private/product" }) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody Entity createV2(@Valid @RequestBody PersistableProductDefinition product, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + // make sure product id is null + product.setId(null); + Long id = productDefinitionFacade.saveProductDefinition(merchantStore, product, language); + Entity returnEntity = new Entity(); + returnEntity.setId(id); + return returnEntity; + + } + + @ResponseStatus(HttpStatus.OK) + @PutMapping(value = { "/private/product/{id}" }) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void updateV2(@PathVariable Long id, + @Valid @RequestBody PersistableProductDefinition product, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + productDefinitionFacade.update(id, product, merchantStore, language); + + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/product/{id}" }) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody ReadableProductDefinition getV2( + @PathVariable Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + ReadableProductDefinition def = productDefinitionFacade.getProduct(merchantStore, id, language); + return def; + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{id}" }, method = RequestMethod.DELETE) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void deleteV2(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + productCommonFacade.deleteProduct(id, merchantStore); + } + + /** + * API for getting a product + * + * @param friendlyUrl + * @param lang ?lang=fr|en + * @param response + * @return ReadableProduct + * @throws Exception + *

    + * /api/product/123 + */ + @RequestMapping(value = { "/product/slug/{friendlyUrl}", + "/product/friendly/{friendlyUrl}" }, method = RequestMethod.GET) + @ApiOperation(httpMethod = "GET", value = "Get a product by friendlyUrl (slug) version 2", notes = "For shop purpose. Specifying ?merchant is " + + "required otherwise it falls back to DEFAULT") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Single product found", response = ReadableProduct.class) }) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableProduct getByfriendlyUrl( + @PathVariable final String friendlyUrl, + @RequestParam(value = "lang", required = false) String lang, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, HttpServletResponse response) throws Exception { + + ReadableProduct product = productFacadeV2.getProductBySeUrl(merchantStore, friendlyUrl, language); + + if (product == null) { + response.sendError(404, "Product not fount for id " + friendlyUrl); + return null; + } + + return product; + } + + + /** + * List products + * Filtering product lists based on product option and option value ?category=1 + * &manufacturer=2 &type=... &lang=en|fr NOT REQUIRED, will use request language + * &start=0 NOT REQUIRED, can be used for pagination &count=10 NOT REQUIRED, can + * be used to limit item count + * + * @param request + * @param response + * @return + * @throws Exception + */ + @RequestMapping(value = "/products", method = RequestMethod.GET) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableProductList list( + @RequestParam(value = "lang", required = false) String lang, + ProductCriteria searchCriterias, + + // page + // 0 + // .. + // n + // allowing + // navigation + @RequestParam(value = "count", required = false, defaultValue = "100") Integer count, // count + // per + // page + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + + if (!StringUtils.isBlank(searchCriterias.getSku())) { + searchCriterias.setCode(searchCriterias.getSku()); + } + + if (!StringUtils.isBlank(searchCriterias.getName())) { + searchCriterias.setProductName(searchCriterias.getName()); + } + + searchCriterias.setMaxCount(count); + searchCriterias.setLanguage(language.getCode()); + + try { + return productFacadeV2.getProductListsByCriterias(merchantStore, language, searchCriterias); + + } catch (Exception e) { + LOGGER.error("Error while filtering products product", e); + throw new ServiceRuntimeException(e); + + } + } + + /** updates price quantity **/ + @ResponseStatus(HttpStatus.OK) + @PatchMapping(value = "/private/product/{sku}", produces = { APPLICATION_JSON_VALUE }) + @ApiOperation(httpMethod = "PATCH", value = "Update product inventory", notes = "Updates product inventory", produces = "application/json", response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public void update( + @PathVariable String sku, + @Valid @RequestBody + LightPersistableProduct product, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + productCommonFacade.update(sku, product, merchantStore, language); + return; + + } + + + /** + * API for getting a product using sku in v2 + * + * @param id + * @param lang ?lang=fr|en|... + * @param response + * @return ReadableProduct + * @throws Exception + *

    + * /api/products/123 + */ + @RequestMapping(value = "/product/{sku}", method = RequestMethod.GET) + @ApiOperation(httpMethod = "GET", value = "Get a product by sku", notes = "For Shop purpose. Specifying ?merchant is required otherwise it falls back to DEFAULT") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Single product found", response = ReadableProduct.class) }) + @ResponseBody + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public ReadableProduct get(@PathVariable final String sku, + @RequestParam(value = "lang", required = false) String lang, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + ReadableProduct product = productFacadeV2.getProductByCode(merchantStore, sku, language); + + + + return product; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v2/product/ProductVariantApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v2/product/ProductVariantApi.java new file mode 100644 index 0000000000..21a65782db --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v2/product/ProductVariantApi.java @@ -0,0 +1,208 @@ +package com.salesmanager.shop.store.api.v2.product; + +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.inject.Inject; +import javax.validation.Valid; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +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.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.model.catalog.product.product.variant.PersistableProductVariant; +import com.salesmanager.shop.model.catalog.product.product.variant.ReadableProductVariant; +import com.salesmanager.shop.model.entity.Entity; +import com.salesmanager.shop.model.entity.EntityExists; +import com.salesmanager.shop.model.entity.ReadableEntityList; +import com.salesmanager.shop.store.api.exception.UnauthorizedException; +import com.salesmanager.shop.store.controller.product.facade.ProductVariantFacade; +import com.salesmanager.shop.store.controller.user.facade.UserFacade; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +/** + * Api to manage productVariant + * + * Product variant allows to specify product + * size, sku and options related to this product variant + * + * @author carlsamson + * + */ +@Controller +@RequestMapping("/api/v2") +@Api(tags = { "Product variants api" }) +@SwaggerDefinition(tags = { + @Tag(name = "Product variants resource", description = "Manage inventory for a given product") }) +public class ProductVariantApi { + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductVariantApi.class); + + @Autowired + private ProductVariantFacade productVariantFacade; + + @Inject + private UserFacade userFacade; + + @ResponseStatus(HttpStatus.CREATED) + @PostMapping(value = { "/private/product/{productId}/variant" }) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public @ResponseBody Entity create( + @Valid @RequestBody PersistableProductVariant variant, + @PathVariable Long productId, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + Long id = productVariantFacade.create(variant, productId, merchantStore, language); + return new Entity(id); + + } + + + @ResponseStatus(HttpStatus.OK) + @PutMapping(value = { "/private/product/{id}/variant/{variantId}" }) + @ApiOperation(httpMethod = "PUT", value = "Update product variant", notes = "", produces = "application/json", response = Void.class) + public @ResponseBody void update(@PathVariable Long id, @PathVariable Long variantId, + @Valid @RequestBody PersistableProductVariant variant, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + productVariantFacade.update(variantId, variant, id, merchantStore, language); + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/product/{id}/variant/{sku}/unique" }, produces = "application/json") + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + @ApiOperation(httpMethod = "GET", value = "Check if option set code already exists", notes = "", response = EntityExists.class) + public @ResponseBody ResponseEntity exists( + @PathVariable Long id, + @PathVariable String sku, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + boolean exist = productVariantFacade.exists(sku, merchantStore, id, language); + return new ResponseEntity(new EntityExists(exist), HttpStatus.OK); + + } + + @GetMapping(value = "/private/product/{id}/variant/{variantId}", produces = "application/json") + @ApiOperation(httpMethod = "GET", value = "Get a productVariant by id", notes = "For administration and shop purpose. Specifying ?merchant is required otherwise it falls back to DEFAULT") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Single product found", response = ReadableProductVariant.class) }) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody ReadableProductVariant get( + @PathVariable final Long id, + @PathVariable Long variantId, + @RequestParam(value = "lang", required = false) String lang, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) throws Exception { + + return productVariantFacade.get(variantId, id, merchantStore, language); + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{id}/variants" }, method = RequestMethod.GET) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody ReadableEntityList list(@PathVariable final Long id, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language, + @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, + @RequestParam(value = "count", required = false, defaultValue = "10") Integer count) { + + return productVariantFacade.list(id, merchantStore, language, page, count); + + } + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/{id}/variant/{variantId}" }, method = RequestMethod.DELETE) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void delete( + @PathVariable Long id, + @PathVariable Long variantId, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + productVariantFacade.delete(variantId, id, merchantStore); + + + } + + + /** + + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = { "/private/product/{id}/{variantId}/image" }, method = RequestMethod.POST) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void addvariantImage( + @PathVariable Long id, + @RequestParam(name = "file", required = true) MultipartFile file, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletRequest request, + HttpServletResponse response) { + + //productOptionFacade.addOptionValueImage(file, id, merchantStore, language); + + + } + + **/ + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v2/product/ProductVariantGroupApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v2/product/ProductVariantGroupApi.java new file mode 100644 index 0000000000..37c32f25d2 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v2/product/ProductVariantGroupApi.java @@ -0,0 +1,201 @@ +package com.salesmanager.shop.store.api.v2.product; + +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.validation.Valid; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +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.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.multipart.MultipartFile; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.model.catalog.product.product.variantGroup.PersistableProductVariantGroup; +import com.salesmanager.shop.model.catalog.product.product.variantGroup.ReadableProductVariantGroup; +import com.salesmanager.shop.model.entity.Entity; +import com.salesmanager.shop.model.entity.ReadableEntityList; +import com.salesmanager.shop.store.api.exception.UnauthorizedException; +import com.salesmanager.shop.store.controller.product.facade.ProductVariantGroupFacade; +import com.salesmanager.shop.store.controller.user.facade.UserFacade; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +@Controller +@RequestMapping("/api/v2") +@Api(tags = { "Product instances group api" }) +@SwaggerDefinition(tags = { + @Tag(name = "Product instances group allows attaching property and images to a group of instances", description = "Manage product instances group") }) +public class ProductVariantGroupApi { + + @Autowired + private ProductVariantGroupFacade productVariantGroupFacade; + + @Autowired + private UserFacade userFacade; + + @ResponseStatus(HttpStatus.CREATED) + @PostMapping(value = { "/private/product/productVariantGroup" }) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + public @ResponseBody Entity create( + @Valid @RequestBody PersistableProductVariantGroup instanceGroup, + @ApiIgnore MerchantStore merchantStore, @ApiIgnore Language language) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + Long id = productVariantGroupFacade.create(instanceGroup, merchantStore, language); + + return new Entity(id); + + } + + @ResponseStatus(HttpStatus.OK) + @PutMapping(value = { "/private/product/productVariantGroup/{id}" }) + @ApiOperation(httpMethod = "PUT", value = "Update product instance group", notes = "", produces = "application/json", response = Void.class) + public @ResponseBody void update(@PathVariable Long id, + @Valid @RequestBody PersistableProductVariantGroup instance, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + productVariantGroupFacade.update(id, instance, merchantStore, language); + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/product/productVariantGroup/{id}" }) + @ApiOperation(httpMethod = "GET", value = "Get product instance group", notes = "", produces = "application/json", response = Void.class) + public @ResponseBody ReadableProductVariantGroup get( + @PathVariable Long id, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + return productVariantGroupFacade.get(id, merchantStore, language); + } + + // delete + + @ResponseStatus(HttpStatus.OK) + @DeleteMapping(value = { "/private/product/productVariantGroup/{id}" }) + @ApiOperation(httpMethod = "DELETE", value = "Delete product instance group", notes = "", produces = "application/json", response = Void.class) + public @ResponseBody void delete(@PathVariable Long id, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + productVariantGroupFacade.delete(id, id, merchantStore); + } + + // list + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/product/{id}/productVariantGroup" }) + @ApiOperation(httpMethod = "GET", value = "Delete product instance group", notes = "", produces = "application/json", response = Void.class) + public @ResponseBody ReadableEntityList list( + @PathVariable final Long id, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + @RequestParam(value = "page", required = false, defaultValue = "0") Integer page, + @RequestParam(value = "count", required = false, defaultValue = "10") Integer count) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + return productVariantGroupFacade.list(id, merchantStore, language, page, count); + } + + // add image + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = { "/private/product/productVariantGroup/{id}/image" }, consumes = { + MediaType.MULTIPART_FORM_DATA_VALUE }, method = RequestMethod.POST) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void addImage( + @PathVariable Long id, + @RequestParam(value = "file", required = true) MultipartFile file, + @RequestParam(value = "order", required = false, defaultValue = "0") Integer position, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + productVariantGroupFacade.addImage(file, id, merchantStore, language); + + } + + // remove image + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { + "/private/product/productVariantGroup/{id}/image/{imageId}" }, method = RequestMethod.DELETE) + public void removeImage(@PathVariable Long id, @PathVariable Long imageId, @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + + userFacade.authorizedGroup(authenticatedUser, Stream.of(Constants.GROUP_SUPERADMIN, Constants.GROUP_ADMIN, + Constants.GROUP_ADMIN_CATALOGUE, Constants.GROUP_ADMIN_RETAIL).collect(Collectors.toList())); + + productVariantGroupFacade.removeImage(imageId, id, merchantStore); + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/api/v2/product/ProductVariationApi.java b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v2/product/ProductVariationApi.java new file mode 100755 index 0000000000..1e9fcc507e --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/api/v2/product/ProductVariationApi.java @@ -0,0 +1,284 @@ +package com.salesmanager.shop.store.api.v2.product; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; + +import org.apache.commons.collections4.CollectionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +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.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.ReadableProductPrice; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductVariant; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductVariantValue; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableSelectedProductVariant; +import com.salesmanager.shop.model.catalog.product.variation.PersistableProductVariation; +import com.salesmanager.shop.model.catalog.product.variation.ReadableProductVariation; +import com.salesmanager.shop.model.entity.Entity; +import com.salesmanager.shop.model.entity.EntityExists; +import com.salesmanager.shop.model.entity.ReadableEntityList; +import com.salesmanager.shop.populator.catalog.ReadableFinalPricePopulator; +import com.salesmanager.shop.store.controller.category.facade.CategoryFacade; +import com.salesmanager.shop.store.controller.product.facade.ProductVariationFacade; +import com.salesmanager.shop.utils.ImageFilePath; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import springfox.documentation.annotations.ApiIgnore; + +/** + * API to manage product variant + * + * The flow is the following + * + * - create a product definition + * - create a product variant + * + * @author Carl Samson + */ +@Controller +@RequestMapping("/api/v2") +@Api(tags = {"Product variation resource (Product variant Api)"}) +@SwaggerDefinition(tags = { + @Tag(name = "Product variation resource", description = "List variations of products by different grouping") +}) +public class ProductVariationApi { + + + @Inject private PricingService pricingService; + + @Inject private ProductService productService; + + @Inject private CategoryFacade categoryFacade; + + @Inject private ProductVariationFacade productVariationFacade; + + + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + + private static final Logger LOGGER = LoggerFactory.getLogger(ProductVariationApi.class); + + /** + * Calculates the price based on selected options if any + * @param id + * @param options + * @param merchantStore + * @param language + * @param response + * @return + * @throws Exception + */ + @RequestMapping(value = "/product/{id}/variation", method = RequestMethod.POST) + @ResponseStatus(HttpStatus.OK) + @ApiOperation( + httpMethod = "POST", + value = "Get product price variation based on selected product", + notes = "", + produces = "application/json", + response = ReadableProductPrice.class) + @ResponseBody + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public ReadableProductPrice calculateVariant( + @PathVariable final Long id, + @RequestBody ReadableSelectedProductVariant options, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletResponse response) + throws Exception { + + Product product = productService.getById(id); + + if (product == null) { + response.sendError(404, "Product not fount for id " + id); + return null; + } + + List ids = options.getOptions(); + + if (CollectionUtils.isEmpty(ids)) { + return null; + } + + List variants = options.getOptions(); + List attributes = new ArrayList(); + + Set productAttributes = product.getAttributes(); + for(ProductAttribute attribute : productAttributes) { + Long option = attribute.getProductOption().getId(); + Long optionValue = attribute.getProductOptionValue().getId(); + for(ReadableProductVariantValue v : variants) { + if(v.getOption().longValue() == option.longValue() + && v.getValue().longValue() == optionValue.longValue()) { + attributes.add(attribute); + } + } + + } + + FinalPrice price = pricingService.calculateProductPrice(product, attributes); + ReadableProductPrice readablePrice = new ReadableProductPrice(); + ReadableFinalPricePopulator populator = new ReadableFinalPricePopulator(); + populator.setPricingService(pricingService); + populator.populate(price, readablePrice, merchantStore, language); + return readablePrice; + } + + + @RequestMapping(value = "/category/{id}/variations", method = RequestMethod.GET) + @ResponseStatus(HttpStatus.OK) + @ApiOperation( + httpMethod = "GET", + value = "Get all variation for all items in a given category", + notes = "", + produces = "application/json", + response = List.class) + @ResponseBody + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") + }) + public List categoryVariantList( + @PathVariable final Long id, //category id + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + HttpServletResponse response) + throws Exception { + + return categoryFacade.categoryProductVariants(id, merchantStore, language); + + } + + @ResponseStatus(HttpStatus.CREATED) + @RequestMapping(value = { "/private/product/variation" }, method = RequestMethod.POST) + @ApiOperation( + httpMethod = "POST", + value = "Creates a new product variant", + notes = "", + produces = "application/json", + response = Void.class) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody Entity create( + @Valid @RequestBody PersistableProductVariation variation, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + Long variantId = productVariationFacade.create(variation, merchantStore, language); + return new Entity(variantId); + + } + + @ResponseStatus(HttpStatus.OK) + @GetMapping(value = { "/private/product/variation/unique" }, produces = MediaType.APPLICATION_JSON_VALUE) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "string", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "string", defaultValue = "en") }) + @ApiOperation(httpMethod = "GET", value = "Check if option set code already exists", notes = "", response = EntityExists.class) + public ResponseEntity exists( + @RequestParam(value = "code") String code, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + boolean isOptionExist = productVariationFacade.exists(code, merchantStore); + return new ResponseEntity(new EntityExists(isOptionExist), HttpStatus.OK); + } + + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/variation/{variationId}" }, method = RequestMethod.GET) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + @ResponseBody + public ReadableProductVariation get( + @PathVariable Long variationId, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + return productVariationFacade.get(variationId, merchantStore, language); + + } + + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/variation/{variationId}" }, method = RequestMethod.PUT) + @ApiImplicitParams({ @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void update( + @Valid @RequestBody PersistableProductVariation variation, + @PathVariable Long variationId, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + variation.setId(variationId); + productVariationFacade.update(variationId, variation, merchantStore, language); + + } + + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/variation/{variationId}" }, method = RequestMethod.DELETE) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public void delete( + @PathVariable Long variationId, + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language) { + + productVariationFacade.delete(variationId, merchantStore); + + } + + + @ResponseStatus(HttpStatus.OK) + @RequestMapping(value = { "/private/product/variations" }, method = RequestMethod.GET) + @ApiImplicitParams({ + @ApiImplicitParam(name = "store", dataType = "String", defaultValue = "DEFAULT"), + @ApiImplicitParam(name = "lang", dataType = "String", defaultValue = "en") }) + public @ResponseBody ReadableEntityList list( + @ApiIgnore MerchantStore merchantStore, + @ApiIgnore Language language, + @RequestParam(value = "page", required = false, defaultValue="0") Integer page, + @RequestParam(value = "count", required = false, defaultValue="10") Integer count) { + + return productVariationFacade.list(merchantStore, language, page, count); + + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/AbstractController.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/AbstractController.java new file mode 100755 index 0000000000..169e400dea --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/AbstractController.java @@ -0,0 +1,62 @@ +/** + * + */ +package com.salesmanager.shop.store.controller; + +import javax.servlet.http.HttpServletRequest; + +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.store.model.paging.PaginationData; + +/** + * @author Umesh A + * + */ +public abstract class AbstractController { + + + /** + * Method which will help to retrieving values from Session + * based on the key being passed to the method. + * @param key + * @return value stored in session corresponding to the key + */ + @SuppressWarnings( "unchecked" ) + protected T getSessionAttribute(final String key, HttpServletRequest request) { + return (T) com.salesmanager.shop.utils.SessionUtil.getSessionAttribute(key, request); + + } + + protected void setSessionAttribute(final String key, final Object value, HttpServletRequest request) { + com.salesmanager.shop.utils.SessionUtil.setSessionAttribute(key, value, request); + } + + + protected void removeAttribute(final String key, HttpServletRequest request) { + com.salesmanager.shop.utils.SessionUtil.removeSessionAttribute(key, request); + } + + protected Language getLanguage(HttpServletRequest request) { + return (Language)request.getAttribute(Constants.LANGUAGE); + } + + protected PaginationData createPaginaionData( final int pageNumber, final int pageSize ) + { + final PaginationData paginaionData = new PaginationData(pageSize,pageNumber); + + return paginaionData; + } + + protected PaginationData calculatePaginaionData( final PaginationData paginationData, final int pageSize, final int resultCount){ + + int currentPage = paginationData.getCurrentPage(); + + + int count = Math.min((currentPage * pageSize), resultCount); + paginationData.setCountByPage(count); + + paginationData.setTotalCount( resultCount ); + return paginationData; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/ControllerConstants.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/ControllerConstants.java new file mode 100755 index 0000000000..8201c12b91 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/ControllerConstants.java @@ -0,0 +1,89 @@ +/** + * + */ +package com.salesmanager.shop.store.controller; + +/** + * Interface contain constant for Controller.These constant will be used throughout + * sm-shop to providing constant values to various Controllers being used in the + * application. + * @author Umesh A + * + */ +public interface ControllerConstants +{ + + final static String REDIRECT="redirect:"; + + interface Tiles{ + interface ShoppingCart{ + final static String shoppingCart="maincart"; + } + + interface Category{ + final static String category="category"; + } + + interface Product{ + final static String product="product"; + } + + interface Items{ + final static String items_manufacturer="items.manufacturer"; + } + + interface Customer{ + final static String customer="customer"; + final static String customerLogon="customerLogon"; + final static String review="review"; + final static String register="register"; + final static String changePassword="customerPassword"; + final static String customerOrders="customerOrders"; + final static String customerOrder="customerOrder"; + final static String Billing="customerAddress"; + final static String EditAddress="editCustomerAddress"; + } + + interface Content{ + final static String content="content"; + final static String contactus="contactus"; + } + + interface Pages{ + final static String notFound="404"; + final static String timeout="timeout"; + } + + interface Merchant{ + final static String contactUs="contactus"; + } + + interface Checkout{ + final static String checkout="checkout"; + final static String confirmation="confirmation"; + } + + interface Search{ + final static String search="search"; + } + + interface Error { + final static String accessDenied = "accessDenied"; + final static String error = "error"; + } + + + + } + + interface Views + { + interface Controllers + { + interface Registration + { + String RegistrationPage = "shop/customer/registration.html"; + } + } + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/country/facade/CountryFacade.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/country/facade/CountryFacade.java new file mode 100755 index 0000000000..40ec09bf6b --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/country/facade/CountryFacade.java @@ -0,0 +1,11 @@ +package com.salesmanager.shop.store.controller.country.facade; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.references.ReadableCountry; +import java.util.List; + +public interface CountryFacade { + List getListCountryZones(Language language, MerchantStore merchantStore); +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/country/facade/CountryFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/country/facade/CountryFacadeImpl.java new file mode 100755 index 0000000000..0c9c1ca999 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/country/facade/CountryFacadeImpl.java @@ -0,0 +1,48 @@ +package com.salesmanager.shop.store.controller.country.facade; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.references.ReadableCountry; +import com.salesmanager.shop.populator.references.ReadableCountryPopulator; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import java.util.List; +import java.util.stream.Collectors; +import javax.inject.Inject; +import org.springframework.stereotype.Service; + +@Service +public class CountryFacadeImpl implements CountryFacade { + + @Inject + private CountryService countryService; + + @Override + public List getListCountryZones(Language language, MerchantStore merchantStore) { + return getListOfCountryZones(language) + .stream() + .map(country -> convertToReadableCountry(country, language, merchantStore)) + .collect(Collectors.toList()); + } + + private ReadableCountry convertToReadableCountry(Country country, Language language, MerchantStore merchantStore) { + try{ + ReadableCountryPopulator populator = new ReadableCountryPopulator(); + return populator.populate(country, new ReadableCountry(), merchantStore, language); + } catch (ConversionException e) { + throw new ConversionRuntimeException(e); + } + } + + private List getListOfCountryZones(Language language) { + try{ + return countryService.listCountryZones(language); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/currency/facade/CurrencyFacade.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/currency/facade/CurrencyFacade.java new file mode 100755 index 0000000000..9efc1961d0 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/currency/facade/CurrencyFacade.java @@ -0,0 +1,9 @@ +package com.salesmanager.shop.store.controller.currency.facade; + +import com.salesmanager.core.model.reference.currency.Currency; +import java.util.List; + +public interface CurrencyFacade { + + List getList(); +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/currency/facade/CurrencyFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/currency/facade/CurrencyFacadeImpl.java new file mode 100755 index 0000000000..65524c9a15 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/currency/facade/CurrencyFacadeImpl.java @@ -0,0 +1,35 @@ +package com.salesmanager.shop.store.controller.currency.facade; + +import com.salesmanager.core.business.services.reference.currency.CurrencyService; +import com.salesmanager.core.model.reference.currency.Currency; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.controller.currency.facade.CurrencyFacade; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import javax.inject.Inject; +import org.springframework.stereotype.Service; + +@Service +public class CurrencyFacadeImpl implements CurrencyFacade { + + @Inject + private CurrencyService currencyService; + + @Override + public List getList() { + List currencyList = currencyService.list(); + if (currencyList.isEmpty()){ + throw new ResourceNotFoundException("No languages found"); + } + Collections.sort(currencyList, new Comparator(){ + + public int compare(Currency o1, Currency o2) + { + return o1.getCode().compareTo(o2.getCode()); + } + }); + return currencyList; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/customer/facade/CustomerFacade.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/customer/facade/CustomerFacade.java new file mode 100755 index 0000000000..4a86ea3828 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/customer/facade/CustomerFacade.java @@ -0,0 +1,191 @@ +/** + * + */ +package com.salesmanager.shop.store.controller.customer.facade; + +import java.util.List; +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.customer.CustomerCriteria; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.shop.model.customer.CustomerEntity; +import com.salesmanager.shop.model.customer.PersistableCustomer; +import com.salesmanager.shop.model.customer.PersistableCustomerReview; +import com.salesmanager.shop.model.customer.ReadableCustomer; +import com.salesmanager.shop.model.customer.ReadableCustomerReview; +import com.salesmanager.shop.model.customer.address.Address; +import com.salesmanager.shop.model.customer.optin.PersistableCustomerOptin; +import com.salesmanager.shop.populator.customer.ReadableCustomerList; + +/** + *

    Customer facade working as a bridge between {@link CustomerService} and Controller + * It will take care about interacting with Service API and doing any pre and post processing + *

    + * + * @author Umesh Awasthi + * @version 2.2.1 - 2.7.0 + * @author carlsamson + * + * + */ +public interface CustomerFacade +{ + + /** + * Method used to fetch customer based on the username and storecode. + * Customer username is unique to each store. + * + * @param userName + * @param store + * @param store + * @param language + * @throws Exception + * + */ + public CustomerEntity getCustomerDataByUserName(final String userName,final MerchantStore store, final Language language) throws Exception; + + /** + * Creates a ReadableCustomer + * @param id + * @param merchantStore + * @param language + * @return + */ + ReadableCustomer getCustomerById(final Long id, final MerchantStore merchantStore, final Language language); + + /** + * Get Customer using unique username + * @param userName + * @param merchantStore + * @param language + * @return + * @throws Exception + */ + ReadableCustomer getByUserName(String userName, MerchantStore merchantStore, Language language); + /** + *

    Method responsible for merging cart during authentication, + * Method will perform following operations + *

  • Merge Customer Shopping Cart with Session Cart if any.
  • + *
  • Convert Customer to {@link CustomerEntity}
  • + *

    + * + * @param customer username of Customer + * @param sessionShoppingCartId session shopping cart, if user already have few items in Cart. + * @throws Exception + */ + public ShoppingCart mergeCart(final Customer customer,final String sessionShoppingCartId,final MerchantStore store,final Language language) throws Exception; + + public Customer getCustomerByUserName(final String userName, final MerchantStore store); + + public boolean checkIfUserExists(final String userName,final MerchantStore store) throws Exception; + + public PersistableCustomer registerCustomer( final PersistableCustomer customer,final MerchantStore merchantStore, final Language language) throws Exception; + + public Address getAddress(final Long userId, final MerchantStore merchantStore,boolean isBillingAddress) throws Exception; + + public void updateAddress( Long userId, MerchantStore merchantStore, Address address, final Language language ) + throws Exception; + + public void setCustomerModelDefaultProperties(Customer customer, MerchantStore store) throws Exception; + + + public void authenticate(Customer customer, String userName, String password) throws Exception; + + Customer getCustomerModel(PersistableCustomer customer, + MerchantStore merchantStore, Language language) throws Exception; + + Customer populateCustomerModel(Customer customerModel, PersistableCustomer customer, + MerchantStore merchantStore, Language language) throws Exception; + + /* + * Creates a Customer from a PersistableCustomer received from REST API + */ + ReadableCustomer create(PersistableCustomer customer, MerchantStore store, Language language); + + /** + * Reset customer password + * @param customer + * @param store + * @param language + * @throws Exception + */ + void resetPassword(Customer customer, MerchantStore store, Language language); + + /** + * Updates a Customer + * @param customer + * @param store + * @throws Exception + */ + PersistableCustomer update(PersistableCustomer customer, MerchantStore store); + + PersistableCustomer update(String userName, PersistableCustomer customer, MerchantStore store); + + /** + * Updates only shipping and billing addresses + * @param customer + * @param store + * @return + */ + void updateAddress(PersistableCustomer customer, MerchantStore store); + + void updateAddress(String userName, PersistableCustomer customer, MerchantStore store); + + /** + * Save or update a CustomerReview + * @param review + * @param store + * @param language + * @throws Exception + */ + PersistableCustomerReview saveOrUpdateCustomerReview(PersistableCustomerReview review, MerchantStore store, Language language); + + /** + * List all customer reviews by reviewed + * @param customer + * @param store + * @param language + * @return + */ + List getAllCustomerReviewsByReviewed(Long customerId, MerchantStore store, Language language); + + /** + * Deletes a customer review + * @param review + * @param store + * @param language + */ + void deleteCustomerReview(Long customerId, Long reviewId, MerchantStore store, Language language); + + /** + * Optin a customer to newsletter + * @param optin + * @param store + * @throws Exception + */ + void optinCustomer(PersistableCustomerOptin optin, MerchantStore store); + + ReadableCustomer getCustomerByNick(String userName, MerchantStore merchantStore, Language language); + + void deleteByNick(String nick); + + void deleteById(Long id); + + void delete(Customer entity); + + ReadableCustomerList getListByStore(MerchantStore store, CustomerCriteria criteria, Language language); + + PersistableCustomerReview createCustomerReview( + Long customerId, + PersistableCustomerReview review, + MerchantStore merchantStore, + Language language); + + PersistableCustomerReview updateCustomerReview(Long id, Long reviewId, PersistableCustomerReview review, MerchantStore store, Language language); + + boolean passwordMatch(String rawPassword, Customer customer); + + void changePassword(Customer customer, String newPassword); +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/customer/facade/CustomerFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/customer/facade/CustomerFacadeImpl.java new file mode 100755 index 0000000000..60fbf4bd00 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/customer/facade/CustomerFacadeImpl.java @@ -0,0 +1,1122 @@ +/** + * + */ +package com.salesmanager.shop.store.controller.customer.facade; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; +import javax.inject.Inject; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.jgroups.util.UUID; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.scheduling.annotation.Async; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.email.Email; +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.customer.optin.CustomerOptinService; +import com.salesmanager.core.business.services.customer.review.CustomerReviewService; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.services.reference.zone.ZoneService; +import com.salesmanager.core.business.services.shoppingcart.ShoppingCartService; +import com.salesmanager.core.business.services.system.EmailService; +import com.salesmanager.core.business.services.system.optin.OptinService; +import com.salesmanager.core.business.services.user.GroupService; +import com.salesmanager.core.business.services.user.PermissionService; +import com.salesmanager.core.business.utils.CoreConfiguration; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.customer.CustomerCriteria; +import com.salesmanager.core.model.customer.CustomerList; +import com.salesmanager.core.model.customer.review.CustomerReview; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.core.model.system.optin.CustomerOptin; +import com.salesmanager.core.model.system.optin.Optin; +import com.salesmanager.core.model.system.optin.OptinType; +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.model.user.GroupType; +import com.salesmanager.core.model.user.Permission; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.constants.EmailConstants; +import com.salesmanager.shop.model.customer.CustomerEntity; +import com.salesmanager.shop.model.customer.PersistableCustomer; +import com.salesmanager.shop.model.customer.PersistableCustomerReview; +import com.salesmanager.shop.model.customer.ReadableCustomer; +import com.salesmanager.shop.model.customer.ReadableCustomerReview; +import com.salesmanager.shop.model.customer.UserAlreadyExistException; +import com.salesmanager.shop.model.customer.address.Address; +import com.salesmanager.shop.model.customer.optin.PersistableCustomerOptin; +import com.salesmanager.shop.populator.customer.CustomerBillingAddressPopulator; +import com.salesmanager.shop.populator.customer.CustomerDeliveryAddressPopulator; +import com.salesmanager.shop.populator.customer.CustomerEntityPopulator; +import com.salesmanager.shop.populator.customer.CustomerPopulator; +import com.salesmanager.shop.populator.customer.PersistableCustomerBillingAddressPopulator; +import com.salesmanager.shop.populator.customer.PersistableCustomerReviewPopulator; +import com.salesmanager.shop.populator.customer.PersistableCustomerShippingAddressPopulator; +import com.salesmanager.shop.populator.customer.ReadableCustomerList; +import com.salesmanager.shop.populator.customer.ReadableCustomerPopulator; +import com.salesmanager.shop.populator.customer.ReadableCustomerReviewPopulator; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.utils.EmailTemplatesUtils; +import com.salesmanager.shop.utils.EmailUtils; +import com.salesmanager.shop.utils.ImageFilePath; +import com.salesmanager.shop.utils.LabelUtils; +import com.salesmanager.shop.utils.LocaleUtils; + + +/** + * Customer Facade work as an abstraction layer between Controller and Service layer. It work as an + * entry point to service layer. + * + * @author Umesh Awasthi + * @version 2.2.1, 2.8.0 + * @modified Carl Samson + * + */ + +@Service("customerFacade") +public class CustomerFacadeImpl implements CustomerFacade { + + private static final Logger LOG = LoggerFactory.getLogger(CustomerFacadeImpl.class); + public final static int USERNAME_LENGTH = 6; + + private final static String RESET_PASSWORD_TPL = "email_template_password_reset_customer.ftl"; + + public final static String ROLE_PREFIX = "ROLE_";// Spring Security 4 + + + @Inject + private CustomerService customerService; + + @Inject + private OptinService optinService; + + @Inject + private CustomerOptinService customerOptinService; + + @Inject + private ShoppingCartService shoppingCartService; + + @Inject + private LanguageService languageService; + + @Inject + private LabelUtils messages; + + @Inject + private CountryService countryService; + + @Inject + private GroupService groupService; + + @Inject + private PermissionService permissionService; + + @Inject + private ZoneService zoneService; + + @Inject + private PasswordEncoder passwordEncoder; + + @Inject + private EmailService emailService; + + @Inject + private EmailTemplatesUtils emailTemplatesUtils; + + @Inject + private AuthenticationManager customerAuthenticationManager; + + @Inject + private CustomerReviewService customerReviewService; + + @Inject + private CoreConfiguration coreConfiguration; + + @Autowired + private CustomerPopulator customerPopulator; + + @Inject + private EmailUtils emailUtils; + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + /** + * Method used to fetch customer based on the username and storecode. Customer username is unique + * to each store. + * + * @param userName + * @param store + * @throws ConversionException + */ + @Override + public CustomerEntity getCustomerDataByUserName(final String userName, final MerchantStore store, + final Language language) throws Exception { + LOG.info("Fetching customer with userName" + userName); + Customer customer = customerService.getByNick(userName); + + if (customer != null) { + LOG.info("Found customer, converting to CustomerEntity"); + try { + CustomerEntityPopulator customerEntityPopulator = new CustomerEntityPopulator(); + return customerEntityPopulator.populate(customer, store, language); // store, language + + } catch (ConversionException ex) { + LOG.error("Error while converting Customer to CustomerEntity", ex); + throw new Exception(ex); + } + } + + return null; + + } + + + /* + * (non-Javadoc) + * + * @see com.salesmanager.web.shop.controller.customer.facade#mergeCart(final Customer + * customerModel, final String sessionShoppingCartId ,final MerchantStore store,final Language + * language) + */ + @Override + public ShoppingCart mergeCart(final Customer customerModel, final String sessionShoppingCartId, + final MerchantStore store, final Language language) throws Exception { + + LOG.debug("Starting merge cart process"); + if (customerModel != null) { + ShoppingCart customerCart = shoppingCartService.getShoppingCart(customerModel, store); + if (StringUtils.isNotBlank(sessionShoppingCartId)) { + ShoppingCart sessionShoppingCart = + shoppingCartService.getByCode(sessionShoppingCartId, store); + if (sessionShoppingCart != null) { + if (customerCart == null) { + if (sessionShoppingCart.getCustomerId() == null) {// saved shopping cart does not belong + // to a customer + LOG.debug("Not able to find any shoppingCart with current customer"); + // give it to the customer + sessionShoppingCart.setCustomerId(customerModel.getId()); + shoppingCartService.saveOrUpdate(sessionShoppingCart); + customerCart = shoppingCartService.getById(sessionShoppingCart.getId(), store); + return customerCart; + // return populateShoppingCartData(customerCart,store,language); + } else { + return null; + } + } else { + if (sessionShoppingCart.getCustomerId() == null) {// saved shopping cart does not belong + // to a customer + // assign it to logged in user + LOG.debug("Customer shopping cart as well session cart is available, merging carts"); + customerCart = + shoppingCartService.mergeShoppingCarts(customerCart, sessionShoppingCart, store); + customerCart = shoppingCartService.getById(customerCart.getId(), store); + return customerCart; + // return populateShoppingCartData(customerCart,store,language); + } else { + if (sessionShoppingCart.getCustomerId().longValue() == customerModel.getId() + .longValue()) { + if (!customerCart.getShoppingCartCode() + .equals(sessionShoppingCart.getShoppingCartCode())) { + // merge carts + LOG.info("Customer shopping cart as well session cart is available"); + customerCart = shoppingCartService.mergeShoppingCarts(customerCart, + sessionShoppingCart, store); + customerCart = shoppingCartService.getById(customerCart.getId(), store); + return customerCart; + // return populateShoppingCartData(customerCart,store,language); + } else { + return customerCart; + // return populateShoppingCartData(sessionShoppingCart,store,language); + } + } else { + // the saved cart belongs to another user + return null; + } + } + + + } + } + } else { + if (customerCart != null) { + // return populateShoppingCartData(customerCart,store,language); + return customerCart; + } + return null; + + } + } + LOG.info( + "Seems some issue with system, unable to find any customer after successful authentication"); + return null; + + } + + + + @Override + //KEEP + public Customer getCustomerByUserName(String userName, MerchantStore store){ + + try { + return customerService.getByNick(userName, store.getId()); + } catch(Exception e) { + throw new ServiceRuntimeException(e); + } + + } + + @Override + public ReadableCustomer getByUserName(String userName, MerchantStore merchantStore, Language language) { + Validate.notNull(userName,"Username cannot be null"); + Validate.notNull(merchantStore,"MerchantStore cannot be null"); + + Customer customerModel = getCustomerByNickAndStoreId(userName, merchantStore); + return convertCustomerToReadableCustomer(customerModel, merchantStore, language); + } + + private Customer getCustomerByNickAndStoreId(String userName, MerchantStore merchantStore) { + return Optional.ofNullable(customerService.getByNick(userName, merchantStore.getId())) + .orElseThrow(() -> new ResourceNotFoundException("No Customer found for ID : " + userName)); + } + + + /** + *

    + * Method to check if given user exists for given username under given store. System treat + * username as unique for a given store, customer is not allowed to use same username twice for a + * given store, however it can be used for different stores. + *

    + * + * @param userName Customer slected userName + * @param store store for which customer want to register + * @return boolean flag indicating if user exists for given store or not + * @throws Exception + * + */ + @Override + public boolean checkIfUserExists(final String userName, final MerchantStore store) + throws Exception { + if (StringUtils.isNotBlank(userName) && store != null) { + Customer customer = customerService.getByNick(userName, store.getId()); + if (customer != null) { + LOG.info("Customer with userName {} already exists for store {} ", userName, + store.getStorename()); + return true; + } + + LOG.info("No customer found with userName {} for store {} ", userName, store.getStorename()); + return false; + + } + LOG.info("Either userName is empty or we have not found any value for store"); + return false; + } + + + @Override + public PersistableCustomer registerCustomer(final PersistableCustomer customer, + final MerchantStore merchantStore, Language language) throws Exception { + LOG.info("Starting customer registration process.."); + + if (userExist(customer.getUserName())) { + throw new UserAlreadyExistException("User already exist"); + } + + Customer customerModel = getCustomerModel(customer, merchantStore, language); + if (customerModel == null) { + LOG.equals("Unable to create customer in system"); + // throw new CustomerRegistrationException( "Unable to register customer" ); + throw new Exception("Unable to register customer"); + } + + LOG.info("About to persist customer to database."); + customerService.saveOrUpdate(customerModel); + + LOG.info("Returning customer data to controller.."); + // return customerEntityPoulator(customerModel,merchantStore); + customer.setId(customerModel.getId()); + return customer; + } + + @Override + public Customer getCustomerModel(final PersistableCustomer customer, + final MerchantStore merchantStore, Language language) throws Exception { + + LOG.info("Starting to populate customer model from customer data"); + Customer customerModel = null; + + customerModel = customerPopulator.populate(customer, merchantStore, language); + // we are creating or resetting a customer + if (StringUtils.isBlank(customerModel.getPassword()) + && !StringUtils.isBlank(customer.getPassword())) { + customerModel.setPassword(customer.getPassword()); + } + // set groups + if (!StringUtils.isBlank(customerModel.getPassword()) + && !StringUtils.isBlank(customerModel.getNick())) { + customerModel.setPassword(passwordEncoder.encode(customer.getPassword())); + setCustomerModelDefaultProperties(customerModel, merchantStore); + } + + + return customerModel; + + } + + + + @Override + public void setCustomerModelDefaultProperties(Customer customer, MerchantStore store) + throws Exception { + Validate.notNull(customer, "Customer object cannot be null"); + if (customer.getId() == null || customer.getId() == 0) { + if (StringUtils.isBlank(customer.getNick())) { + String userName = customer.getEmailAddress(); + customer.setNick(userName); + } + if (StringUtils.isBlank(customer.getPassword())) { + String password = new String(UUID.generateRandomBytes()); + String encodedPassword = passwordEncoder.encode(password); + customer.setPassword(encodedPassword); + } + } + + if (CollectionUtils.isEmpty(customer.getGroups())) { + List groups = getListOfGroups(GroupType.CUSTOMER); + for (Group group : groups) { + if (group.getGroupName().equals(Constants.GROUP_CUSTOMER)) { + customer.getGroups().add(group); + } + } + + } + + } + + + + public void authenticate(Customer customer, String userName, String password) throws Exception { + + Validate.notNull(customer, "Customer cannot be null"); + + Collection authorities = new ArrayList(); + GrantedAuthority role = + new SimpleGrantedAuthority(ROLE_PREFIX + Constants.PERMISSION_CUSTOMER_AUTHENTICATED);// required + // to + // login + authorities.add(role); + List groupsId = new ArrayList(); + List groups = customer.getGroups(); + if (groups != null) { + for (Group group : groups) { + groupsId.add(group.getId()); + + } + if (groupsId != null && groupsId.size() > 0) { + List permissions = permissionService.getPermissions(groupsId); + for (Permission permission : permissions) { + GrantedAuthority auth = new SimpleGrantedAuthority(permission.getPermissionName()); + authorities.add(auth); + } + } + } + + Authentication authenticationToken = + new UsernamePasswordAuthenticationToken(userName, password, authorities); + + Authentication authentication = customerAuthenticationManager.authenticate(authenticationToken); + + SecurityContextHolder.getContext().setAuthentication(authentication); + + } + + + @Override + public Address getAddress(Long userId, final MerchantStore merchantStore, + boolean isBillingAddress) throws Exception { + LOG.info("Fetching customer for id {} ", userId); + Address address = null; + final Customer customerModel = customerService.getById(userId); + + if (customerModel == null) { + LOG.error("Customer with ID {} does not exists..", userId); + // throw new CustomerNotFoundException( "customer with given id does not exists" ); + throw new Exception("customer with given id does not exists"); + } + + if (isBillingAddress) { + LOG.info("getting billing address.."); + CustomerBillingAddressPopulator billingAddressPopulator = + new CustomerBillingAddressPopulator(); + address = billingAddressPopulator.populate(customerModel, merchantStore, + merchantStore.getDefaultLanguage()); + address.setBillingAddress(true); + return address; + } + + LOG.info("getting Delivery address.."); + CustomerDeliveryAddressPopulator deliveryAddressPopulator = + new CustomerDeliveryAddressPopulator(); + return deliveryAddressPopulator.populate(customerModel, merchantStore, + merchantStore.getDefaultLanguage()); + + } + + + @Override + public void updateAddress(Long userId, MerchantStore merchantStore, Address address, + final Language language) throws Exception { + + Customer customerModel = customerService.getById(userId); + Map countriesMap = countryService.getCountriesMap(language); + Country country = countriesMap.get(address.getCountry()); + + if (customerModel == null) { + LOG.error("Customer with ID {} does not exists..", userId); + // throw new CustomerNotFoundException( "customer with given id does not exists" ); + throw new Exception("customer with given id does not exists"); + + } + if (address.isBillingAddress()) { + LOG.info("updating customer billing address.."); + PersistableCustomerBillingAddressPopulator billingAddressPopulator = + new PersistableCustomerBillingAddressPopulator(); + customerModel = billingAddressPopulator.populate(address, customerModel, merchantStore, + merchantStore.getDefaultLanguage()); + customerModel.getBilling().setCountry(country); + if (StringUtils.isNotBlank(address.getZone())) { + Zone zone = zoneService.getByCode(address.getZone()); + if (zone == null) { + throw new ConversionException("Unsuported zone code " + address.getZone()); + } + customerModel.getBilling().setZone(zone); + customerModel.getBilling().setState(null); + + } else { + customerModel.getBilling().setZone(null); + } + + } else { + LOG.info("updating customer shipping address.."); + PersistableCustomerShippingAddressPopulator shippingAddressPopulator = + new PersistableCustomerShippingAddressPopulator(); + customerModel = shippingAddressPopulator.populate(address, customerModel, merchantStore, + merchantStore.getDefaultLanguage()); + customerModel.getDelivery().setCountry(country); + if (StringUtils.isNotBlank(address.getZone())) { + Zone zone = zoneService.getByCode(address.getZone()); + if (zone == null) { + throw new ConversionException("Unsuported zone code " + address.getZone()); + } + + customerModel.getDelivery().setZone(zone); + customerModel.getDelivery().setState(null); + + } else { + customerModel.getDelivery().setZone(null); + } + + } + + + // same update address with customer model + this.customerService.saveOrUpdate(customerModel); + + } + + @Override + public ReadableCustomer getCustomerById(final Long id, final MerchantStore merchantStore, + final Language language) { + + Customer customerModel = Optional.ofNullable(customerService.getById(id)) + .orElseThrow(() -> new ResourceNotFoundException("No Customer found for ID : " + id)); + + return convertCustomerToReadableCustomer(customerModel, merchantStore, language); + } + + + @Override + public Customer populateCustomerModel(Customer customerModel, PersistableCustomer customer, + MerchantStore merchantStore, Language language) throws Exception { + LOG.info("Starting to populate customer model from customer data"); + + + customerModel = customerPopulator.populate(customer, customerModel, merchantStore, language); + + LOG.info("About to persist customer to database."); + customerService.saveOrUpdate(customerModel); + return customerModel; + } + + + @Override + public ReadableCustomer create(PersistableCustomer customer, MerchantStore store, Language language) { + + Validate.notNull(customer, "Customer cannot be null"); + Validate.notNull(customer.getEmailAddress(), "Customer email address is required"); + + //set customer user name + customer.setUserName(customer.getEmailAddress()); + if (userExist(customer.getUserName())) { + throw new ServiceRuntimeException("User already exist"); + } + //end user exists + + Customer customerToPopulate = convertPersistableCustomerToCustomer(customer, store); + try { + setCustomerModelDefaultProperties(customerToPopulate, store); + } catch (Exception e) { + throw new ServiceRuntimeException("Cannot set default customer properties",e); + } + saveCustomer(customerToPopulate); + customer.setId(customerToPopulate.getId()); + + notifyNewCustomer(customer, store, customerToPopulate.getDefaultLanguage()); + //convert to readable + return convertCustomerToReadableCustomer(customerToPopulate, store, language); + + + } + + private void saveCustomer(Customer customerToPopulate) { + try{ + customerService.save(customerToPopulate); + } catch (ServiceException exception) { + throw new ServiceRuntimeException(exception); + } + + } + + private boolean userExist(String userName) { + return Optional.ofNullable(customerService.getByNick(userName)) + .isPresent(); + } + + private List getListOfGroups(GroupType groupType) { + try{ + return groupService.listGroup(groupType); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + + } + + private Customer convertPersistableCustomerToCustomer(PersistableCustomer customer, MerchantStore store) { + + Customer cust = new Customer(); + + try{ + customerPopulator.populate(customer, cust, store, store.getDefaultLanguage()); + } catch (ConversionException e) { + throw new ConversionRuntimeException(e); + } + + + List groups = getListOfGroups(GroupType.CUSTOMER); + cust.setGroups(groups); + + String password = customer.getPassword(); + if (StringUtils.isBlank(password)) { + password = new String(UUID.generateRandomBytes()); + customer.setPassword(password); + } + + + return cust; + + } + + @Async + private void notifyNewCustomer(PersistableCustomer customer, MerchantStore store, Language lang) { + System.out.println("Customer notification"); + long startTime = System.nanoTime(); + Locale customerLocale = LocaleUtils.getLocale(lang); + String shopSchema = coreConfiguration.getProperty("SHOP_SCHEME"); + emailTemplatesUtils.sendRegistrationEmail(customer, store, customerLocale, shopSchema); + long endTime = System.nanoTime(); + long duration = (endTime - startTime)/1000; + System.out.println("End Notification " + duration); + } + + + private PersistableCustomer updateAuthCustomer(PersistableCustomer customer, MerchantStore store) { + + if (customer.getId() == null || customer.getId() == 0) { + throw new ServiceRuntimeException("Can't update a customer with null id"); + } + + Customer cust = customerService.getById(customer.getId()); + + try{ + customerPopulator.populate(customer, cust, store, store.getDefaultLanguage()); + } catch (ConversionException e) { + throw new ConversionRuntimeException(e); + } + + saveCustomer(cust); + customer.setId(cust.getId()); + + return customer; + } + + + @Override + public PersistableCustomer update(PersistableCustomer customer, MerchantStore store) { + + if (customer.getId() == null || customer.getId() == 0) { + throw new ServiceRuntimeException("Can't update a customer with null id"); + } + + Customer cust = customerService.getById(customer.getId()); + + try{ + customerPopulator.populate(customer, cust, store, store.getDefaultLanguage()); + } catch (ConversionException e) { + throw new ConversionRuntimeException(e); + } + + String password = customer.getPassword(); + if (StringUtils.isBlank(password)) { + password = new String(UUID.generateRandomBytes()); + customer.setPassword(password); + } + + saveCustomer(cust); + customer.setId(cust.getId()); + + return customer; + } + + + @Override + public PersistableCustomerReview saveOrUpdateCustomerReview(PersistableCustomerReview reviewTO, MerchantStore store, + Language language) { + CustomerReview review = convertPersistableCustomerReviewToCustomerReview(reviewTO, store, language); + createReview(review); + reviewTO.setId(review.getId()); + return reviewTO; + } + + private void createReview(CustomerReview review) { + try{ + customerReviewService.create(review); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + + } + + private CustomerReview convertPersistableCustomerReviewToCustomerReview( + PersistableCustomerReview review, MerchantStore store, Language language) { + PersistableCustomerReviewPopulator populator = new PersistableCustomerReviewPopulator(); + populator.setCustomerService(customerService); + populator.setLanguageService(languageService); + try{ + return populator.populate(review, new CustomerReview(), store, language); + } catch (ConversionException e) { + throw new ConversionRuntimeException(e); + } + } + + + @Override + public List getAllCustomerReviewsByReviewed(Long customerId, + MerchantStore store, Language language) { + + //customer exist + Customer customer = getCustomerById(customerId); + Validate.notNull(customer, "Reviewed customer cannot be null"); + + return customerReviewService.getByReviewedCustomer(customer) + .stream() + .map( + customerReview -> + convertCustomerReviewToReadableCustomerReview(customerReview, store, language)) + .collect(Collectors.toList()); + } + + private ReadableCustomerReview convertCustomerReviewToReadableCustomerReview( + CustomerReview customerReview, MerchantStore store, Language language) { + try{ + ReadableCustomerReviewPopulator populator = new ReadableCustomerReviewPopulator(); + return populator.populate(customerReview, new ReadableCustomerReview(), store, language); + } catch (ConversionException e){ + throw new ConversionRuntimeException(e); + } + } + + private Customer getCustomerById(Long customerId) { + return Optional.ofNullable(customerService.getById(customerId)) + .orElseThrow(() -> new ResourceNotFoundException("Customer id " + customerId + " does not exists")); + } + + + @Override + public void deleteCustomerReview(Long customerId, Long reviewId, MerchantStore store, Language language) { + + CustomerReview customerReview = getCustomerReviewById(reviewId); + + if(!customerReview.getReviewedCustomer().getId().equals(customerId)) { + throw new ResourceNotFoundException("Customer review with id " + reviewId + " does not exist for this customer"); + } + deleteCustomerReview(customerReview); + } + + private CustomerReview getCustomerReviewById(Long reviewId) { + return Optional.ofNullable(customerReviewService.getById(reviewId)) + .orElseThrow(() -> new ResourceNotFoundException("Customer review with id " + reviewId + " does not exist")); + } + + private void deleteCustomerReview(CustomerReview review) { + try{ + customerReviewService.delete(review); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + } + + + @Override + public void optinCustomer(PersistableCustomerOptin optin, MerchantStore store) { + // check if customer optin exists + Optin optinDef = getOptinByCode(store); + + CustomerOptin customerOptin = getCustomerOptinByEmailAddress(optin.getEmail(), store, OptinType.NEWSLETTER); + + if (customerOptin != null) { + // exists update + customerOptin.setEmail(optin.getEmail()); + customerOptin.setFirstName(optin.getFirstName()); + customerOptin.setLastName(optin.getLastName()); + } else { + customerOptin = new com.salesmanager.core.model.system.optin.CustomerOptin(); + customerOptin.setEmail(optin.getEmail()); + customerOptin.setFirstName(optin.getFirstName()); + customerOptin.setLastName(optin.getLastName()); + customerOptin.setOptinDate(new Date()); + customerOptin.setOptin(optinDef); + customerOptin.setMerchantStore(store); + } + saveCustomerOption(customerOptin); + } + + private void saveCustomerOption(CustomerOptin customerOptin) { + try { + customerOptinService.save(customerOptin); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + } + + private Optin getOptinByCode(MerchantStore store) { + try{ + return Optional.ofNullable(optinService.getOptinByCode(store, OptinType.NEWSLETTER.name())) + .orElseThrow(() -> new ResourceNotFoundException("Optin newsletter does not exist")); + } catch (ServiceException e){ + throw new ServiceRuntimeException(e); + } + } + + private CustomerOptin getCustomerOptinByEmailAddress(String optinEmail, + MerchantStore store, OptinType optinType) { + try{ + return customerOptinService.findByEmailAddress(store, optinEmail, optinType.name()); + } catch (ServiceException e){ + throw new ServiceRuntimeException(e); + } + + } + + + @Override + public void resetPassword(Customer customer, MerchantStore store, Language language) { + + + String password = new String(UUID.generateRandomBytes()); + String encodedPassword = passwordEncoder.encode(password); + + customer.setPassword(encodedPassword); + + try { + customerService.saveOrUpdate(customer); + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + + + Locale locale = languageService.toLocale(language, store); + + // send email + + try { + + // creation of a user, send an email + String[] storeEmail = {store.getStoreEmailAddress()}; + + + Map templateTokens = + emailUtils.createEmailObjectsMap(imageUtils.getContextPath(), store, messages, locale); + templateTokens.put(EmailConstants.LABEL_HI, messages.getMessage("label.generic.hi", locale)); + templateTokens.put(EmailConstants.EMAIL_CUSTOMER_FIRSTNAME, + customer.getBilling().getFirstName()); + templateTokens.put(EmailConstants.EMAIL_CUSTOMER_LASTNAME, + customer.getBilling().getLastName()); + templateTokens.put(EmailConstants.EMAIL_RESET_PASSWORD_TXT, + messages.getMessage("email.customer.resetpassword.text", locale)); + templateTokens.put(EmailConstants.EMAIL_CONTACT_OWNER, + messages.getMessage("email.contactowner", storeEmail, locale)); + templateTokens.put(EmailConstants.EMAIL_PASSWORD_LABEL, + messages.getMessage("label.generic.password", locale)); + templateTokens.put(EmailConstants.EMAIL_CUSTOMER_PASSWORD, password); + + + Email email = new Email(); + email.setFrom(store.getStorename()); + email.setFromEmail(store.getStoreEmailAddress()); + email.setSubject(messages.getMessage("label.generic.changepassword", locale)); + email.setTo(customer.getEmailAddress()); + email.setTemplateName(RESET_PASSWORD_TPL); + email.setTemplateTokens(templateTokens); + + + + emailService.sendHtmlEmail(store, email); + + } catch (Exception e) { + LOG.error("Cannot send email to customer", e); + } + + + } + + @Override + public ReadableCustomer getCustomerByNick(String userName, MerchantStore merchantStore, + Language language) { + Customer customer = getByNick(userName); + return convertCustomerToReadableCustomer(customer, merchantStore, language); + } + + @Override + public void deleteByNick(String userName) { + Customer customer = getByNick(userName); + delete(customer); + } + + private Customer getByNick(String userName) { + return Optional.ofNullable(customerService.getByNick(userName)) + .orElseThrow(() -> new ResourceNotFoundException("No Customer found for ID : " + userName)); + } + + @Override + public void delete(Customer entity) { + try{ + customerService.delete(entity); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + } + + @Override + public ReadableCustomerList getListByStore(MerchantStore store, CustomerCriteria criteria, + Language language) { + CustomerList customerList = customerService.getListByStore(store, criteria); + return convertCustomerListToReadableCustomerList(customerList, store, language); + } + + private ReadableCustomerList convertCustomerListToReadableCustomerList( + CustomerList customerList, MerchantStore store, Language language) { + List readableCustomers = customerList.getCustomers() + .stream() + .map(customer -> convertCustomerToReadableCustomer(customer, store, language)) + .collect(Collectors.toList()); + + ReadableCustomerList readableCustomerList = new ReadableCustomerList(); + readableCustomerList.setCustomers(readableCustomers); + readableCustomerList.setTotalPages(Math.toIntExact(customerList.getTotalCount())); + return readableCustomerList; + } + + private ReadableCustomer convertCustomerToReadableCustomer(Customer customer, MerchantStore merchantStore, Language language) { + ReadableCustomerPopulator populator = new ReadableCustomerPopulator(); + try{ + return populator.populate(customer, new ReadableCustomer(), merchantStore, language); + } catch (ConversionException e) { + throw new ConversionRuntimeException(e); + } + } + + @Override + public PersistableCustomerReview createCustomerReview( + Long customerId, + PersistableCustomerReview review, + MerchantStore merchantStore, + Language language) { + + // rating already exist + Optional customerReview = + Optional.ofNullable( + customerReviewService.getByReviewerAndReviewed(review.getCustomerId(), customerId)); + + if(customerReview.isPresent()) { + throw new ServiceRuntimeException("A review already exist for this customer and product"); + } + + // rating maximum 5 + if (review.getRating() > Constants.MAX_REVIEW_RATING_SCORE) { + throw new ServiceRuntimeException("Maximum rating score is " + Constants.MAX_REVIEW_RATING_SCORE); + } + + review.setReviewedCustomer(customerId); + + saveOrUpdateCustomerReview(review, merchantStore, language); + + return review; + } + + @Override + public PersistableCustomerReview updateCustomerReview(Long id, Long reviewId, PersistableCustomerReview review, + MerchantStore store, Language language) { + + CustomerReview customerReview = getCustomerReviewById(reviewId); + + if(! customerReview.getReviewedCustomer().getId().equals(id)) { + throw new ResourceNotFoundException("Customer review with id " + reviewId + " does not exist for this customer"); + } + + //rating maximum 5 + if(review.getRating()>Constants.MAX_REVIEW_RATING_SCORE) { + throw new ServiceRuntimeException("Maximum rating score is " + Constants.MAX_REVIEW_RATING_SCORE); + } + + review.setReviewedCustomer(id); + return review; + } + + + @Override + public void deleteById(Long id) { + Customer customer = getCustomerById(id); + delete(customer); + + } + + + @Override + public void updateAddress(PersistableCustomer customer, MerchantStore store) { + + + if(customer.getBilling() != null) { + Validate.notNull(customer.getBilling(), "Billing address can not be null"); + Validate.notNull(customer.getBilling().getAddress(), "Billing address can not be null"); + Validate.notNull(customer.getBilling().getCity(), "Billing city can not be null"); + Validate.notNull(customer.getBilling().getPostalCode(), "Billing postal code can not be null"); + Validate.notNull(customer.getBilling().getCountry(), "Billing country can not be null"); + } + if(customer.getDelivery() == null) { + customer.setDelivery(customer.getBilling()); + } else { + + if(StringUtils.isBlank(customer.getDelivery().getAddress())) { + customer.getDelivery().setAddress(customer.getBilling().getAddress()); + } + if(StringUtils.isBlank(customer.getDelivery().getCity())) { + customer.getDelivery().setAddress(customer.getBilling().getCity()); + } + if(StringUtils.isBlank(customer.getDelivery().getPostalCode())) { + customer.getDelivery().setAddress(customer.getBilling().getPostalCode()); + } + if(StringUtils.isBlank(customer.getDelivery().getCountryCode())) { + customer.getDelivery().setAddress(customer.getDelivery().getCountryCode()); + } + } + + try { + //update billing + if(customer.getBilling() != null) { + customer.getBilling().setBillingAddress(true); + updateAddress(customer.getId(), store, customer.getBilling(), store.getDefaultLanguage()); + } + + + //update delivery + if(customer.getDelivery() != null) { + customer.getDelivery().setBillingAddress(false); + updateAddress(customer.getId(), store, customer.getDelivery(), store.getDefaultLanguage()); + } + + } catch (Exception e) { + throw new ServiceRuntimeException("Error while updating customer address"); + } + + + } + + + @Override + public void updateAddress(String userName, PersistableCustomer customer, MerchantStore store) { + + ReadableCustomer customerModel = getByUserName(userName, store, store.getDefaultLanguage()); + customer.setId(customerModel.getId()); + customer.setUserName(userName); + updateAddress(customer, store); + + } + + + @Override + public PersistableCustomer update(String userName, PersistableCustomer customer, + MerchantStore store) { + ReadableCustomer customerModel = getByUserName(userName, store, store.getDefaultLanguage()); + customer.setId(customerModel.getId()); + customer.setUserName(userName); + return updateAuthCustomer(customer, store); + } + + + @Override + public boolean passwordMatch(String rawPassword, Customer customer) { + return passwordEncoder.matches(rawPassword, customer.getPassword()); + } + + + @Override + public void changePassword(Customer customer, String newPassword) { + String encoded = passwordEncoder.encode(newPassword); + customer.setPassword(encoded); + try { + customerService.update(customer); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while changing password", e); + } + + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/error/ShopErrorController.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/error/ShopErrorController.java new file mode 100755 index 0000000000..15e2444560 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/error/ShopErrorController.java @@ -0,0 +1,92 @@ +package com.salesmanager.shop.store.controller.error; + +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.servlet.ModelAndView; + +@ControllerAdvice("com.salesmanager.shop.store.controller") +public class ShopErrorController { + + + private static final Logger LOGGER = LoggerFactory.getLogger(ShopErrorController.class); + + + @ExceptionHandler(Exception.class) + @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) + @Produces({MediaType.APPLICATION_JSON}) + public ModelAndView handleException(Exception ex) { + + LOGGER.error("Error page controller",ex); + + ModelAndView model = null; + if(ex instanceof AccessDeniedException) { + + model = new ModelAndView("error/access_denied"); + + } else { + + model = new ModelAndView("error/generic_error"); + model.addObject("stackError", ExceptionUtils.getStackTrace(ex)); + model.addObject("errMsg", ex.getMessage()); + + } + + return model; + + } + + + + @ExceptionHandler(RuntimeException.class) + @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) + @Produces({MediaType.APPLICATION_JSON}) + public ModelAndView handleRuntimeException(Exception ex) { + + LOGGER.error("Error page controller",ex); + + ModelAndView model = null; + + + model = new ModelAndView("error/generic_error"); + model.addObject("stackError", ExceptionUtils.getStackTrace(ex)); + model.addObject("errMsg", ex.getMessage()); + + + + + return model; + + } + + /** + * Generic exception catch allpage + * @param ex + * @return + */ + @RequestMapping(value="/error", method=RequestMethod.GET) + public ModelAndView handleCatchAllException(Model model) { + + + ModelAndView modelAndView = null; + + + modelAndView = new ModelAndView("error/generic_error"); + + return modelAndView; + + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/language/facade/LanguageFacade.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/language/facade/LanguageFacade.java new file mode 100755 index 0000000000..d17af55707 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/language/facade/LanguageFacade.java @@ -0,0 +1,9 @@ +package com.salesmanager.shop.store.controller.language.facade; + +import com.salesmanager.core.model.reference.language.Language; +import java.util.List; + +public interface LanguageFacade { + + List getLanguages(); +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/language/facade/LanguageFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/language/facade/LanguageFacadeImpl.java new file mode 100755 index 0000000000..bd9a332281 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/language/facade/LanguageFacadeImpl.java @@ -0,0 +1,31 @@ +package com.salesmanager.shop.store.controller.language.facade; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import java.util.List; +import javax.inject.Inject; +import org.springframework.stereotype.Service; + +@Service +public class LanguageFacadeImpl implements LanguageFacade { + + @Inject + private LanguageService languageService; + + @Override + public List getLanguages() { + try{ + List languages = languageService.getLanguages(); + if (languages.isEmpty()) { + throw new ResourceNotFoundException("No languages found"); + } + return languages; + } catch (ServiceException e){ + throw new ServiceRuntimeException(e); + } + + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/marketplace/facade/MarketPlaceFacade.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/marketplace/facade/MarketPlaceFacade.java new file mode 100755 index 0000000000..5ff84fe658 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/marketplace/facade/MarketPlaceFacade.java @@ -0,0 +1,35 @@ +package com.salesmanager.shop.store.controller.marketplace.facade; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.system.optin.OptinType; +import com.salesmanager.shop.model.marketplace.ReadableMarketPlace; +import com.salesmanager.shop.model.system.ReadableOptin; + +/** + * Builds market places objects for shop and REST api + * @author c.samson + * + */ +public interface MarketPlaceFacade { + + + /** + * Get a MarketPlace from store code + * @param store + * @param lang + * @return + * @throws Exception + */ + ReadableMarketPlace get(String store, Language lang) ; + + /** + * Finds an optin by merchant and type + * @param store + * @param type + * @return + * @throws Exception + */ + ReadableOptin findByMerchantAndType(MerchantStore store, OptinType type); + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/marketplace/facade/MarketPlaceFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/marketplace/facade/MarketPlaceFacadeImpl.java new file mode 100755 index 0000000000..cec68702a5 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/marketplace/facade/MarketPlaceFacadeImpl.java @@ -0,0 +1,72 @@ +package com.salesmanager.shop.store.controller.marketplace.facade; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import java.util.Optional; +import javax.inject.Inject; + +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.services.system.optin.OptinService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.system.optin.Optin; +import com.salesmanager.core.model.system.optin.OptinType; +import com.salesmanager.shop.model.marketplace.ReadableMarketPlace; +import com.salesmanager.shop.model.store.ReadableMerchantStore; +import com.salesmanager.shop.model.system.ReadableOptin; +import com.salesmanager.shop.populator.system.ReadableOptinPopulator; +import com.salesmanager.shop.store.controller.store.facade.StoreFacade; + +@Component +public class MarketPlaceFacadeImpl implements MarketPlaceFacade { + + @Inject + private StoreFacade storeFacade; + + @Inject + private OptinService optinService; + + @Override + public ReadableMarketPlace get(String store, Language lang) { + ReadableMerchantStore readableStore = storeFacade.getByCode(store, lang); + return createReadableMarketPlace(readableStore); + } + + private ReadableMarketPlace createReadableMarketPlace(ReadableMerchantStore readableStore) { + //TODO add info from Entity + ReadableMarketPlace marketPlace = new ReadableMarketPlace(); + marketPlace.setStore(readableStore); + return marketPlace; + } + + @Override + public ReadableOptin findByMerchantAndType(MerchantStore store, OptinType type) { + Optin optin = getOptinByMerchantAndType(store, type); + return convertOptinToReadableOptin(store, optin); + } + + private Optin getOptinByMerchantAndType(MerchantStore store, OptinType type) { + try{ + return Optional.ofNullable(optinService.getOptinByMerchantAndType(store, type)) + .orElseThrow(() -> new ResourceNotFoundException("Option not found")); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + + } + + private ReadableOptin convertOptinToReadableOptin(MerchantStore store, Optin optin) { + try{ + ReadableOptinPopulator populator = new ReadableOptinPopulator(); + return populator.populate(optin, null, store, null); + } catch (ConversionException e) { + throw new ConversionRuntimeException(e); + } + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/optin/OptinFacade.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/optin/OptinFacade.java new file mode 100755 index 0000000000..0d70723be1 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/optin/OptinFacade.java @@ -0,0 +1,11 @@ +package com.salesmanager.shop.store.controller.optin; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.system.PersistableOptin; +import com.salesmanager.shop.model.system.ReadableOptin; + +public interface OptinFacade { + + ReadableOptin create(PersistableOptin persistableOptin, MerchantStore merchantStore, Language language); +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/optin/OptinFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/optin/OptinFacadeImpl.java new file mode 100755 index 0000000000..2b87369426 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/optin/OptinFacadeImpl.java @@ -0,0 +1,44 @@ +package com.salesmanager.shop.store.controller.optin; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.system.optin.OptinService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.system.optin.Optin; +import com.salesmanager.shop.mapper.optin.PersistableOptinMapper; +import com.salesmanager.shop.mapper.optin.ReadableOptinMapper; +import com.salesmanager.shop.model.system.PersistableOptin; +import com.salesmanager.shop.model.system.ReadableOptin; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import javax.inject.Inject; +import org.springframework.stereotype.Service; + +@Service +public class OptinFacadeImpl implements OptinFacade { + + @Inject + private OptinService optinService; + + @Inject + private ReadableOptinMapper readableOptinConverter; + @Inject + private PersistableOptinMapper persistableOptinConverter; + + @Override + public ReadableOptin create( + PersistableOptin persistableOptin, MerchantStore merchantStore, Language language) { + Optin optinEntity = persistableOptinConverter.convert(persistableOptin, merchantStore, language); + Optin savedOptinEntity = createOptin(optinEntity); + return readableOptinConverter.convert(savedOptinEntity, merchantStore, language); + } + + private Optin createOptin(Optin optinEntity) { + try{ + optinService.create(optinEntity); + return optinEntity; + } catch (ServiceException e){ + throw new ServiceRuntimeException(e); + } + + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/order/facade/OrderFacade.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/order/facade/OrderFacade.java new file mode 100755 index 0000000000..465a446a32 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/order/facade/OrderFacade.java @@ -0,0 +1,205 @@ +package com.salesmanager.shop.store.controller.order.facade; + +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import com.salesmanager.core.model.order.orderstatus.OrderStatus; +import org.springframework.validation.BindingResult; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.order.OrderCriteria; +import com.salesmanager.core.model.order.OrderTotalSummary; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.payments.TransactionType; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.model.shipping.ShippingSummary; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.shop.model.customer.PersistableCustomer; +import com.salesmanager.shop.model.order.ShopOrder; +import com.salesmanager.shop.model.order.history.PersistableOrderStatusHistory; +import com.salesmanager.shop.model.order.history.ReadableOrderStatusHistory; +import com.salesmanager.shop.model.order.transaction.ReadableTransaction; + + +public interface OrderFacade { + + ShopOrder initializeOrder(MerchantStore store, Customer customer, ShoppingCart shoppingCart, Language language) throws Exception; + void refreshOrder(ShopOrder order, MerchantStore store, Customer customer, ShoppingCart shoppingCart, Language language) throws Exception; + /** used in website **/ + OrderTotalSummary calculateOrderTotal(MerchantStore store, ShopOrder order, Language language) throws Exception; + /** used in the API **/ + OrderTotalSummary calculateOrderTotal(MerchantStore store, com.salesmanager.shop.model.order.v0.PersistableOrder order, Language language) throws Exception; + + /** process a valid order **/ + Order processOrder(ShopOrder order, Customer customer, MerchantStore store, Language language) throws ServiceException; + /** process a valid order against an initial transaction **/ + Order processOrder(ShopOrder order, Customer customer, Transaction transaction, MerchantStore store, Language language) throws ServiceException; + /** process a valid order submitted from the API **/ + Order processOrder(com.salesmanager.shop.model.order.v1.PersistableOrder order, Customer customer, MerchantStore store, Language language, Locale locale) throws ServiceException; + + + + /** creates a working copy of customer when the user is anonymous **/ + Customer initEmptyCustomer(MerchantStore store); + List getShipToCountry(MerchantStore store, Language language) + throws Exception; + + /** + * Get a ShippingQuote based on merchant configuration and items to be shipped + * @param cart + * @param order + * @param store + * @param language + * @return + * @throws Exception + */ + ShippingQuote getShippingQuote(PersistableCustomer customer, ShoppingCart cart, ShopOrder order, + MerchantStore store, Language language) throws Exception; + + ShippingQuote getShippingQuote(Customer customer, ShoppingCart cart, com.salesmanager.shop.model.order.v0.PersistableOrder order, + MerchantStore store, Language language) throws Exception; + + ShippingQuote getShippingQuote(Customer customer, ShoppingCart cart, + MerchantStore store, Language language) throws Exception; + + /** + * Creates a ShippingSummary object for OrderTotal calculation based on a ShippingQuote + * @param quote + * @param store + * @param language + * @return + */ + ShippingSummary getShippingSummary(ShippingQuote quote, MerchantStore store, Language language); + + /** + * Validates an order submitted from the web application + * @param order + * @param bindingResult + * @param messagesResult + * @param store + * @param locale + * @throws ServiceException + */ + void validateOrder(ShopOrder order, BindingResult bindingResult, + Map messagesResult, MerchantStore store, + Locale locale) throws ServiceException; + + /** + * Creates a ReadableOrder object from an orderId + * @param orderId + * @param store + * @param language + * @return + * @throws Exception + */ + com.salesmanager.shop.model.order.v0.ReadableOrder getReadableOrder(Long orderId, MerchantStore store, Language language); + + /** + * List of orderstatus history + * @param orderId + * @param store + * @param language + * @return + */ + List getReadableOrderHistory(Long orderId, MerchantStore store, Language language); + + + /** + *

    Method used to fetch all orders associated with customer customer. + * It will used current customer ID to fetch all orders which has been + * placed by customer for current store.

    + * + * @param customer currently logged in customer + * @param store store associated with current customer + * @return ReadableOrderList + * @throws Exception + */ + + com.salesmanager.shop.model.order.v0.ReadableOrderList getReadableOrderList(MerchantStore store, Customer customer, int start, + int maxCount, Language language) throws Exception; + + + /** + *

    Method used to fetch all orders associated with customer customer. + * It will used current customer ID to fetch all orders which has been + * placed by customer for current store.

    + * + * @return ReadableOrderList + * @throws Exception + */ + + com.salesmanager.shop.model.order.v0.ReadableOrderList getReadableOrderList(OrderCriteria criteria, MerchantStore store); + + + /** + * Get a list of Order on which payment capture must be done + * @param store + * @param startDate + * @param endDate + * @param language + * @return + * @throws Exception + */ + com.salesmanager.shop.model.order.v0.ReadableOrderList getCapturableOrderList(MerchantStore store, Date startDate, Date endDate, + Language language) throws Exception; + + /** + * Capture a pre-authorized transaction. Candidate order ids can be obtained from + * getCapturableOrderList + * @param store + * @param order + * @param customer + * @return + * @throws Exception + */ + ReadableTransaction captureOrder(MerchantStore store, Order order, Customer customer, Language language) throws Exception; + + /** + * Returns next TransactionType expected if any. + */ + TransactionType nextTransaction(Long orderId, MerchantStore store); + + /** + * Get orders for a given store + * @param store + * @param start + * @param maxCount + * @param language + * @return + * @throws Exception + */ + com.salesmanager.shop.model.order.v0.ReadableOrderList getReadableOrderList(MerchantStore store, int start, + int maxCount, Language language) throws Exception; + + /** + * Adds a status to an order status history + * @param status + * @param id + * @param store + */ + void createOrderStatus(PersistableOrderStatusHistory status, Long id, MerchantStore store); + + /** + * Updates order customer + * Only updates customer information from the order + * It won't update customer object from Customer entity + * @param orderId + * @param customer + * @param store + */ + void updateOrderCustomre(Long orderId, PersistableCustomer customer, MerchantStore store); + + List listTransactions (Long orderId, MerchantStore store); + + /** + * Update Order status and create order_status_history record + */ + void updateOrderStatus(Order order, OrderStatus newStatus, MerchantStore store); +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/order/facade/OrderFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/order/facade/OrderFacadeImpl.java new file mode 100755 index 0000000000..0da643be26 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/order/facade/OrderFacadeImpl.java @@ -0,0 +1,1648 @@ +package com.salesmanager.shop.store.controller.order.facade; + +import java.math.BigDecimal; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.springframework.validation.BindingResult; +import org.springframework.validation.FieldError; +import org.springframework.validation.ObjectError; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService; +import com.salesmanager.core.business.services.catalog.product.file.DigitalProductService; +import com.salesmanager.core.business.services.order.OrderService; +import com.salesmanager.core.business.services.payments.PaymentService; +import com.salesmanager.core.business.services.payments.TransactionService; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.zone.ZoneService; +import com.salesmanager.core.business.services.shipping.ShippingQuoteService; +import com.salesmanager.core.business.services.shipping.ShippingService; +import com.salesmanager.core.business.services.shoppingcart.ShoppingCartService; +import com.salesmanager.core.business.utils.CoreConfiguration; +import com.salesmanager.core.business.utils.CreditCardUtils; +import com.salesmanager.core.business.utils.ProductPriceUtils; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.common.Billing; +import com.salesmanager.core.model.common.Delivery; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.order.OrderCriteria; +import com.salesmanager.core.model.order.OrderList; +import com.salesmanager.core.model.order.OrderSummary; +import com.salesmanager.core.model.order.OrderTotalSummary; +import com.salesmanager.core.model.order.attributes.OrderAttribute; +import com.salesmanager.core.model.order.orderproduct.OrderProduct; +import com.salesmanager.core.model.order.orderstatus.OrderStatus; +import com.salesmanager.core.model.order.orderstatus.OrderStatusHistory; +import com.salesmanager.core.model.order.payment.CreditCard; +import com.salesmanager.core.model.payments.CreditCardPayment; +import com.salesmanager.core.model.payments.CreditCardType; +import com.salesmanager.core.model.payments.Payment; +import com.salesmanager.core.model.payments.PaymentType; +import com.salesmanager.core.model.payments.Transaction; +import com.salesmanager.core.model.payments.TransactionType; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shipping.ShippingProduct; +import com.salesmanager.core.model.shipping.ShippingQuote; +import com.salesmanager.core.model.shipping.ShippingSummary; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.core.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.shop.model.customer.PersistableCustomer; +import com.salesmanager.shop.model.customer.ReadableCustomer; +import com.salesmanager.shop.model.customer.address.Address; +import com.salesmanager.shop.model.order.OrderEntity; +import com.salesmanager.shop.model.order.PersistableOrderProduct; +import com.salesmanager.shop.model.order.ReadableOrderProduct; +import com.salesmanager.shop.model.order.ShopOrder; +import com.salesmanager.shop.model.order.history.PersistableOrderStatusHistory; +import com.salesmanager.shop.model.order.history.ReadableOrderStatusHistory; +import com.salesmanager.shop.model.order.total.OrderTotal; +import com.salesmanager.shop.model.order.transaction.ReadableTransaction; +import com.salesmanager.shop.populator.customer.CustomerPopulator; +import com.salesmanager.shop.populator.customer.PersistableCustomerPopulator; +import com.salesmanager.shop.populator.order.OrderProductPopulator; +import com.salesmanager.shop.populator.order.PersistableOrderApiPopulator; +import com.salesmanager.shop.populator.order.ReadableOrderPopulator; +import com.salesmanager.shop.populator.order.ReadableOrderProductPopulator; +import com.salesmanager.shop.populator.order.ShoppingCartItemPopulator; +import com.salesmanager.shop.populator.order.transaction.PersistablePaymentPopulator; +import com.salesmanager.shop.populator.order.transaction.ReadableTransactionPopulator; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.customer.facade.CustomerFacade; +import com.salesmanager.shop.store.controller.shoppingCart.facade.ShoppingCartFacade; +import com.salesmanager.shop.utils.DateUtil; +import com.salesmanager.shop.utils.EmailTemplatesUtils; +import com.salesmanager.shop.utils.ImageFilePath; +import com.salesmanager.shop.utils.LabelUtils; +import com.salesmanager.shop.utils.LocaleUtils; + +@Service("orderFacade") +public class OrderFacadeImpl implements OrderFacade { + + private static final Logger LOGGER = LoggerFactory.getLogger(OrderFacadeImpl.class); + + @Inject + private OrderService orderService; + @Inject + private ProductService productService; + @Inject + private ProductAttributeService productAttributeService; + @Inject + private ShoppingCartService shoppingCartService; + @Inject + private DigitalProductService digitalProductService; + @Inject + private ShippingService shippingService; + @Inject + private CustomerFacade customerFacade; + @Inject + private PricingService pricingService; + @Inject + private ShoppingCartFacade shoppingCartFacade; + @Inject + private ShippingQuoteService shippingQuoteService; + @Inject + private CoreConfiguration coreConfiguration; + @Inject + private PaymentService paymentService; + @Inject + private CountryService countryService; + @Inject + private ZoneService zoneService; + + + @Autowired + private PersistableOrderApiPopulator persistableOrderApiPopulator; + + @Autowired + private ReadableOrderPopulator readableOrderPopulator; + + @Autowired + private CustomerPopulator customerPopulator; + + @Autowired + private TransactionService transactionService; + + @Inject + private EmailTemplatesUtils emailTemplatesUtils; + + @Inject + private LabelUtils messages; + + @Autowired + private ProductPriceUtils productPriceUtils; + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + @Override + public ShopOrder initializeOrder(MerchantStore store, Customer customer, ShoppingCart shoppingCart, + Language language) throws Exception { + + // assert not null shopping cart items + + ShopOrder order = new ShopOrder(); + + OrderStatus orderStatus = OrderStatus.ORDERED; + order.setOrderStatus(orderStatus); + + if (customer == null) { + customer = this.initEmptyCustomer(store); + } + + PersistableCustomer persistableCustomer = persistableCustomer(customer, store, language); + order.setCustomer(persistableCustomer); + + // keep list of shopping cart items for core price calculation + List items = new ArrayList(shoppingCart.getLineItems()); + order.setShoppingCartItems(items); + + return order; + } + + @Override + public OrderTotalSummary calculateOrderTotal(MerchantStore store, ShopOrder order, Language language) + throws Exception { + + Customer customer = customerFacade.getCustomerModel(order.getCustomer(), store, language); + OrderTotalSummary summary = calculateOrderTotal(store, customer, order, language); + this.setOrderTotals(order, summary); + return summary; + } + + @Override + public OrderTotalSummary calculateOrderTotal(MerchantStore store, + com.salesmanager.shop.model.order.v0.PersistableOrder order, Language language) throws Exception { + + List orderProducts = order.getOrderProductItems(); + + ShoppingCartItemPopulator populator = new ShoppingCartItemPopulator(); + populator.setProductAttributeService(productAttributeService); + populator.setProductService(productService); + populator.setShoppingCartService(shoppingCartService); + + List items = new ArrayList(); + for (PersistableOrderProduct orderProduct : orderProducts) { + ShoppingCartItem item = populator.populate(orderProduct, new ShoppingCartItem(), store, language); + items.add(item); + } + + Customer customer = customer(order.getCustomer(), store, language); + + OrderTotalSummary summary = this.calculateOrderTotal(store, customer, order, language); + + return summary; + } + + private OrderTotalSummary calculateOrderTotal(MerchantStore store, Customer customer, + com.salesmanager.shop.model.order.v0.PersistableOrder order, Language language) throws Exception { + + OrderTotalSummary orderTotalSummary = null; + + OrderSummary summary = new OrderSummary(); + + if (order instanceof ShopOrder) { + ShopOrder o = (ShopOrder) order; + summary.setProducts(o.getShoppingCartItems()); + + if (o.getShippingSummary() != null) { + summary.setShippingSummary(o.getShippingSummary()); + } + + if (!StringUtils.isBlank(o.getCartCode())) { + + ShoppingCart shoppingCart = shoppingCartFacade.getShoppingCartModel(o.getCartCode(), store); + + // promo code + if (!StringUtils.isBlank(shoppingCart.getPromoCode())) { + Date promoDateAdded = shoppingCart.getPromoAdded();// promo + // valid + // 1 day + Instant instant = promoDateAdded.toInstant(); + ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault()); + LocalDate date = zdt.toLocalDate(); + // date added < date + 1 day + LocalDate tomorrow = LocalDate.now().plusDays(1); + if (date.isBefore(tomorrow)) { + summary.setPromoCode(shoppingCart.getPromoCode()); + } else { + // clear promo + shoppingCart.setPromoCode(null); + shoppingCartService.saveOrUpdate(shoppingCart); + } + } + + } + + orderTotalSummary = orderService.caculateOrderTotal(summary, customer, store, language); + } else { + // need Set of ShoppingCartItem + // PersistableOrder not implemented + throw new Exception("calculateOrderTotal not yet implemented for PersistableOrder"); + } + + return orderTotalSummary; + + } + + private PersistableCustomer persistableCustomer(Customer customer, MerchantStore store, Language language) + throws Exception { + + PersistableCustomerPopulator customerPopulator = new PersistableCustomerPopulator(); + PersistableCustomer persistableCustomer = customerPopulator.populate(customer, new PersistableCustomer(), store, + language); + return persistableCustomer; + + } + + private Customer customer(PersistableCustomer customer, MerchantStore store, Language language) throws Exception { + + Customer cust = customerPopulator.populate(customer, new Customer(), store, language); + return cust; + + } + + private void setOrderTotals(OrderEntity order, OrderTotalSummary summary) { + + List totals = new ArrayList(); + List orderTotals = summary.getTotals(); + for (com.salesmanager.core.model.order.OrderTotal t : orderTotals) { + OrderTotal total = new OrderTotal(); + total.setCode(t.getOrderTotalCode()); + total.setTitle(t.getTitle()); + total.setValue(t.getValue()); + totals.add(total); + } + + order.setTotals(totals); + + } + + /** + * Submitted object must be valided prior to the invocation of this method + */ + @Override + public Order processOrder(ShopOrder order, Customer customer, MerchantStore store, Language language) + throws ServiceException { + + return processOrderModel(order, customer, null, store, language); + + } + + @Override + public Order processOrder(ShopOrder order, Customer customer, Transaction transaction, MerchantStore store, + Language language) throws ServiceException { + + return processOrderModel(order, customer, transaction, store, language); + + } + + /** + * Commit an order + * @param order + * @param customer + * @param transaction + * @param store + * @param language + * @return + * @throws ServiceException + */ + private Order processOrderModel(ShopOrder order, Customer customer, Transaction transaction, MerchantStore store, + Language language) throws ServiceException { + + try { + + if (order.isShipToBillingAdress()) {// customer shipping is billing + PersistableCustomer orderCustomer = order.getCustomer(); + Address billing = orderCustomer.getBilling(); + orderCustomer.setDelivery(billing); + } + + Order modelOrder = new Order(); + modelOrder.setDatePurchased(new Date()); + modelOrder.setBilling(customer.getBilling()); + modelOrder.setDelivery(customer.getDelivery()); + modelOrder.setPaymentModuleCode(order.getPaymentModule()); + modelOrder.setPaymentType(PaymentType.valueOf(order.getPaymentMethodType())); + modelOrder.setShippingModuleCode(order.getShippingModule()); + modelOrder.setCustomerAgreement(order.isCustomerAgreed()); + modelOrder.setLocale(LocaleUtils.getLocale(store));// set the store + // locale based + // on the + // country for + // order $ + // formatting + + List shoppingCartItems = order.getShoppingCartItems(); + Set orderProducts = new LinkedHashSet(); + + if (!StringUtils.isBlank(order.getComments())) { + OrderStatusHistory statusHistory = new OrderStatusHistory(); + statusHistory.setStatus(OrderStatus.ORDERED); + statusHistory.setOrder(modelOrder); + statusHistory.setDateAdded(new Date()); + statusHistory.setComments(order.getComments()); + modelOrder.getOrderHistory().add(statusHistory); + } + + OrderProductPopulator orderProductPopulator = new OrderProductPopulator(); + orderProductPopulator.setDigitalProductService(digitalProductService); + orderProductPopulator.setProductAttributeService(productAttributeService); + orderProductPopulator.setProductService(productService); + String shoppingCartCode = null; + + for (ShoppingCartItem item : shoppingCartItems) { + + if(shoppingCartCode == null && item.getShoppingCart()!=null) { + shoppingCartCode = item.getShoppingCart().getShoppingCartCode(); + } + + /** + * Before processing order quantity of item must be > 0 + */ + + Product product = productService.getBySku(item.getSku(), store, language); + if (product == null) { + throw new ServiceException(ServiceException.EXCEPTION_INVENTORY_MISMATCH); + } + + LOGGER.debug("Validate inventory"); + for (ProductAvailability availability : product.getAvailabilities()) { + if (availability.getRegion().equals(Constants.ALL_REGIONS)) { + int qty = availability.getProductQuantity(); + if (qty < item.getQuantity()) { + throw new ServiceException(ServiceException.EXCEPTION_INVENTORY_MISMATCH); + } + } + } + + OrderProduct orderProduct = new OrderProduct(); + orderProduct = orderProductPopulator.populate(item, orderProduct, store, language); + orderProduct.setOrder(modelOrder); + orderProducts.add(orderProduct); + } + + modelOrder.setOrderProducts(orderProducts); + + OrderTotalSummary summary = order.getOrderTotalSummary(); + List totals = summary.getTotals(); + + // re-order totals + Collections.sort(totals, new Comparator() { + public int compare(com.salesmanager.core.model.order.OrderTotal x, + com.salesmanager.core.model.order.OrderTotal y) { + if (x.getSortOrder() == y.getSortOrder()) + return 0; + return x.getSortOrder() < y.getSortOrder() ? -1 : 1; + } + + }); + + Set modelTotals = new LinkedHashSet(); + for (com.salesmanager.core.model.order.OrderTotal total : totals) { + total.setOrder(modelOrder); + modelTotals.add(total); + } + + modelOrder.setOrderTotal(modelTotals); + modelOrder.setTotal(order.getOrderTotalSummary().getTotal()); + + // order misc objects + modelOrder.setCurrency(store.getCurrency()); + modelOrder.setMerchant(store); + + // customer object + orderCustomer(customer, modelOrder, language); + + // populate shipping information + if (!StringUtils.isBlank(order.getShippingModule())) { + modelOrder.setShippingModuleCode(order.getShippingModule()); + } + + String paymentType = order.getPaymentMethodType(); + Payment payment = new Payment(); + payment.setPaymentType(PaymentType.valueOf(paymentType)); + payment.setAmount(order.getOrderTotalSummary().getTotal()); + payment.setModuleName(order.getPaymentModule()); + payment.setCurrency(modelOrder.getCurrency()); + + if (order.getPayment() != null && order.getPayment().get("paymentToken") != null) {// set + // token + String paymentToken = order.getPayment().get("paymentToken"); + Map paymentMetaData = new HashMap(); + payment.setPaymentMetaData(paymentMetaData); + paymentMetaData.put("paymentToken", paymentToken); + } + + if (PaymentType.CREDITCARD.name().equals(paymentType)) { + + payment = new CreditCardPayment(); + ((CreditCardPayment) payment).setCardOwner(order.getPayment().get("creditcard_card_holder")); + ((CreditCardPayment) payment) + .setCredidCardValidationNumber(order.getPayment().get("creditcard_card_cvv")); + ((CreditCardPayment) payment).setCreditCardNumber(order.getPayment().get("creditcard_card_number")); + ((CreditCardPayment) payment) + .setExpirationMonth(order.getPayment().get("creditcard_card_expirationmonth")); + ((CreditCardPayment) payment) + .setExpirationYear(order.getPayment().get("creditcard_card_expirationyear")); + + Map paymentMetaData = order.getPayment(); + payment.setPaymentMetaData(paymentMetaData); + payment.setPaymentType(PaymentType.valueOf(paymentType)); + payment.setAmount(order.getOrderTotalSummary().getTotal()); + payment.setModuleName(order.getPaymentModule()); + payment.setCurrency(modelOrder.getCurrency()); + + CreditCardType creditCardType = null; + String cardType = order.getPayment().get("creditcard_card_type"); + + // supported credit cards + if (CreditCardType.AMEX.name().equalsIgnoreCase(cardType)) { + creditCardType = CreditCardType.AMEX; + } else if (CreditCardType.VISA.name().equalsIgnoreCase(cardType)) { + creditCardType = CreditCardType.VISA; + } else if (CreditCardType.MASTERCARD.name().equalsIgnoreCase(cardType)) { + creditCardType = CreditCardType.MASTERCARD; + } else if (CreditCardType.DINERS.name().equalsIgnoreCase(cardType)) { + creditCardType = CreditCardType.DINERS; + } else if (CreditCardType.DISCOVERY.name().equalsIgnoreCase(cardType)) { + creditCardType = CreditCardType.DISCOVERY; + } + + ((CreditCardPayment) payment).setCreditCard(creditCardType); + + if (creditCardType != null) { + + CreditCard cc = new CreditCard(); + cc.setCardType(creditCardType); + cc.setCcCvv(((CreditCardPayment) payment).getCredidCardValidationNumber()); + cc.setCcOwner(((CreditCardPayment) payment).getCardOwner()); + cc.setCcExpires(((CreditCardPayment) payment).getExpirationMonth() + "-" + + ((CreditCardPayment) payment).getExpirationYear()); + + // hash credit card number + if (!StringUtils.isBlank(cc.getCcNumber())) { + String maskedNumber = CreditCardUtils + .maskCardNumber(order.getPayment().get("creditcard_card_number")); + cc.setCcNumber(maskedNumber); + modelOrder.setCreditCard(cc); + } + + } + + } + + if (PaymentType.PAYPAL.name().equals(paymentType)) { + + // check for previous transaction + if (transaction == null) { + throw new ServiceException("payment.error"); + } + + payment = new com.salesmanager.core.model.payments.PaypalPayment(); + + ((com.salesmanager.core.model.payments.PaypalPayment) payment) + .setPayerId(transaction.getTransactionDetails().get("PAYERID")); + ((com.salesmanager.core.model.payments.PaypalPayment) payment) + .setPaymentToken(transaction.getTransactionDetails().get("TOKEN")); + + } + + modelOrder.setShoppingCartCode(shoppingCartCode); + modelOrder.setPaymentModuleCode(order.getPaymentModule()); + payment.setModuleName(order.getPaymentModule()); + + if (transaction != null) { + orderService.processOrder(modelOrder, customer, order.getShoppingCartItems(), summary, payment, store); + } else { + orderService.processOrder(modelOrder, customer, order.getShoppingCartItems(), summary, payment, + transaction, store); + } + + return modelOrder; + + } catch (ServiceException se) {// may be invalid credit card + throw se; + } catch (Exception e) { + throw new ServiceException(e); + } + + } + + private void orderCustomer(Customer customer, Order order, Language language) throws Exception { + + // populate customer + order.setBilling(customer.getBilling()); + order.setDelivery(customer.getDelivery()); + order.setCustomerEmailAddress(customer.getEmailAddress()); + order.setCustomerId(customer.getId()); + //set username + if(! customer.isAnonymous() && !StringUtils.isBlank(customer.getPassword())) { + customer.setNick(customer.getEmailAddress()); + } + + } + + @Override + public Customer initEmptyCustomer(MerchantStore store) { + + Customer customer = new Customer(); + Billing billing = new Billing(); + billing.setCountry(store.getCountry()); + billing.setZone(store.getZone()); + billing.setState(store.getStorestateprovince()); + /** empty postal code for initial quote **/ + // billing.setPostalCode(store.getStorepostalcode()); + customer.setBilling(billing); + + Delivery delivery = new Delivery(); + delivery.setCountry(store.getCountry()); + delivery.setZone(store.getZone()); + delivery.setState(store.getStorestateprovince()); + /** empty postal code for initial quote **/ + // delivery.setPostalCode(store.getStorepostalcode()); + customer.setDelivery(delivery); + + return customer; + } + + @Override + public void refreshOrder(ShopOrder order, MerchantStore store, Customer customer, ShoppingCart shoppingCart, + Language language) throws Exception { + if (customer == null && order.getCustomer() != null) { + order.getCustomer().setId(0L);// reset customer id + } + + if (customer != null) { + PersistableCustomer persistableCustomer = persistableCustomer(customer, store, language); + order.setCustomer(persistableCustomer); + } + + List items = new ArrayList(shoppingCart.getLineItems()); + order.setShoppingCartItems(items); + + return; + } + + @Override + public ShippingQuote getShippingQuote(PersistableCustomer persistableCustomer, ShoppingCart cart, ShopOrder order, + MerchantStore store, Language language) throws Exception { + + // create shipping products + List shippingProducts = shoppingCartService.createShippingProduct(cart); + + if (CollectionUtils.isEmpty(shippingProducts)) { + return null;// products are virtual + } + + Customer customer = customerFacade.getCustomerModel(persistableCustomer, store, language); + + Delivery delivery = new Delivery(); + + // adjust shipping and billing + if (order.isShipToBillingAdress() && !order.isShipToDeliveryAddress()) { + + Billing billing = customer.getBilling(); + + String postalCode = billing.getPostalCode(); + postalCode = validatePostalCode(postalCode); + + delivery.setAddress(billing.getAddress()); + delivery.setCompany(billing.getCompany()); + delivery.setCity(billing.getCity()); + delivery.setPostalCode(billing.getPostalCode()); + delivery.setState(billing.getState()); + delivery.setCountry(billing.getCountry()); + delivery.setZone(billing.getZone()); + } else { + delivery = customer.getDelivery(); + } + + ShippingQuote quote = shippingService.getShippingQuote(cart.getId(), store, delivery, shippingProducts, + language); + + return quote; + + } + + private String validatePostalCode(String postalCode) { + + String patternString = "__";// this one is set in the template + if (postalCode.contains(patternString)) { + postalCode = null; + } + return postalCode; + } + + @Override + public List getShipToCountry(MerchantStore store, Language language) throws Exception { + + List shippingCountriesList = shippingService.getShipToCountryList(store, language); + return shippingCountriesList; + + } + + /** + * ShippingSummary contains the subset of information of a ShippingQuote + */ + @Override + public ShippingSummary getShippingSummary(ShippingQuote quote, MerchantStore store, Language language) { + + ShippingSummary summary = new ShippingSummary(); + if (quote.getSelectedShippingOption() != null) { + summary.setShippingQuote(true); + summary.setFreeShipping(quote.isFreeShipping()); + summary.setTaxOnShipping(quote.isApplyTaxOnShipping()); + summary.setHandling(quote.getHandlingFees()); + summary.setShipping(quote.getSelectedShippingOption().getOptionPrice()); + summary.setShippingOption(quote.getSelectedShippingOption().getOptionName()); + summary.setShippingModule(quote.getShippingModuleCode()); + summary.setShippingOptionCode(quote.getSelectedShippingOption().getOptionCode()); + + if (quote.getDeliveryAddress() != null) { + summary.setDeliveryAddress(quote.getDeliveryAddress()); + } + + } + + return summary; + } + + @Override + public void validateOrder(ShopOrder order, BindingResult bindingResult, Map messagesResult, + MerchantStore store, Locale locale) throws ServiceException { + + Validate.notNull(messagesResult, "messagesResult should not be null"); + + try { + + // Language language = (Language)request.getAttribute("LANGUAGE"); + + // validate order shipping and billing + if (StringUtils.isBlank(order.getCustomer().getBilling().getFirstName())) { + FieldError error = new FieldError("customer.billing.firstName", "customer.billing.firstName", + messages.getMessage("NotEmpty.customer.firstName", locale)); + bindingResult.addError(error); + messagesResult.put("customer.billing.firstName", + messages.getMessage("NotEmpty.customer.firstName", locale)); + } + + if (StringUtils.isBlank(order.getCustomer().getBilling().getLastName())) { + FieldError error = new FieldError("customer.billing.lastName", "customer.billing.lastName", + messages.getMessage("NotEmpty.customer.lastName", locale)); + bindingResult.addError(error); + messagesResult.put("customer.billing.lastName", + messages.getMessage("NotEmpty.customer.lastName", locale)); + } + + if (StringUtils.isBlank(order.getCustomer().getEmailAddress())) { + FieldError error = new FieldError("customer.emailAddress", "customer.emailAddress", + messages.getMessage("NotEmpty.customer.emailAddress", locale)); + bindingResult.addError(error); + messagesResult.put("customer.emailAddress", + messages.getMessage("NotEmpty.customer.emailAddress", locale)); + } + + if (StringUtils.isBlank(order.getCustomer().getBilling().getAddress())) { + FieldError error = new FieldError("customer.billing.address", "customer.billing.address", + messages.getMessage("NotEmpty.customer.billing.address", locale)); + bindingResult.addError(error); + messagesResult.put("customer.billing.address", + messages.getMessage("NotEmpty.customer.billing.address", locale)); + } + + if (StringUtils.isBlank(order.getCustomer().getBilling().getCity())) { + FieldError error = new FieldError("customer.billing.city", "customer.billing.city", + messages.getMessage("NotEmpty.customer.billing.city", locale)); + bindingResult.addError(error); + messagesResult.put("customer.billing.city", + messages.getMessage("NotEmpty.customer.billing.city", locale)); + } + + if (StringUtils.isBlank(order.getCustomer().getBilling().getCountry())) { + FieldError error = new FieldError("customer.billing.country", "customer.billing.country", + messages.getMessage("NotEmpty.customer.billing.country", locale)); + bindingResult.addError(error); + messagesResult.put("customer.billing.country", + messages.getMessage("NotEmpty.customer.billing.country", locale)); + } + + if (StringUtils.isBlank(order.getCustomer().getBilling().getZone()) + && StringUtils.isBlank(order.getCustomer().getBilling().getStateProvince())) { + FieldError error = new FieldError("customer.billing.stateProvince", "customer.billing.stateProvince", + messages.getMessage("NotEmpty.customer.billing.stateProvince", locale)); + bindingResult.addError(error); + messagesResult.put("customer.billing.stateProvince", + messages.getMessage("NotEmpty.customer.billing.stateProvince", locale)); + } + + if (StringUtils.isBlank(order.getCustomer().getBilling().getPhone())) { + FieldError error = new FieldError("customer.billing.phone", "customer.billing.phone", + messages.getMessage("NotEmpty.customer.billing.phone", locale)); + bindingResult.addError(error); + messagesResult.put("customer.billing.phone", + messages.getMessage("NotEmpty.customer.billing.phone", locale)); + } + + if (StringUtils.isBlank(order.getCustomer().getBilling().getPostalCode())) { + FieldError error = new FieldError("customer.billing.postalCode", "customer.billing.postalCode", + messages.getMessage("NotEmpty.customer.billing.postalCode", locale)); + bindingResult.addError(error); + messagesResult.put("customer.billing.postalCode", + messages.getMessage("NotEmpty.customer.billing.postalCode", locale)); + } + + if (!order.isShipToBillingAdress()) { + + if (StringUtils.isBlank(order.getCustomer().getDelivery().getFirstName())) { + FieldError error = new FieldError("customer.delivery.firstName", "customer.delivery.firstName", + messages.getMessage("NotEmpty.customer.shipping.firstName", locale)); + bindingResult.addError(error); + messagesResult.put("customer.delivery.firstName", + messages.getMessage("NotEmpty.customer.shipping.firstName", locale)); + } + + if (StringUtils.isBlank(order.getCustomer().getDelivery().getLastName())) { + FieldError error = new FieldError("customer.delivery.lastName", "customer.delivery.lastName", + messages.getMessage("NotEmpty.customer.shipping.lastName", locale)); + bindingResult.addError(error); + messagesResult.put("customer.delivery.lastName", + messages.getMessage("NotEmpty.customer.shipping.lastName", locale)); + } + + if (StringUtils.isBlank(order.getCustomer().getDelivery().getAddress())) { + FieldError error = new FieldError("customer.delivery.address", "customer.delivery.address", + messages.getMessage("NotEmpty.customer.shipping.address", locale)); + bindingResult.addError(error); + messagesResult.put("customer.delivery.address", + messages.getMessage("NotEmpty.customer.shipping.address", locale)); + } + + if (StringUtils.isBlank(order.getCustomer().getDelivery().getCity())) { + FieldError error = new FieldError("customer.delivery.city", "customer.delivery.city", + messages.getMessage("NotEmpty.customer.shipping.city", locale)); + bindingResult.addError(error); + messagesResult.put("customer.delivery.city", + messages.getMessage("NotEmpty.customer.shipping.city", locale)); + } + + if (StringUtils.isBlank(order.getCustomer().getDelivery().getCountry())) { + FieldError error = new FieldError("customer.delivery.country", "customer.delivery.country", + messages.getMessage("NotEmpty.customer.shipping.country", locale)); + bindingResult.addError(error); + messagesResult.put("customer.delivery.country", + messages.getMessage("NotEmpty.customer.shipping.country", locale)); + } + + if (StringUtils.isBlank(order.getCustomer().getDelivery().getZone()) + && StringUtils.isBlank(order.getCustomer().getDelivery().getStateProvince())) { + FieldError error = new FieldError("customer.delivery.stateProvince", + "customer.delivery.stateProvince", + messages.getMessage("NotEmpty.customer.shipping.stateProvince", locale)); + bindingResult.addError(error); + messagesResult.put("customer.delivery.stateProvince", + messages.getMessage("NotEmpty.customer.shipping.stateProvince", locale)); + } + + if (StringUtils.isBlank(order.getCustomer().getDelivery().getPostalCode())) { + FieldError error = new FieldError("customer.delivery.postalCode", "customer.delivery.postalCode", + messages.getMessage("NotEmpty.customer.shipping.postalCode", locale)); + bindingResult.addError(error); + messagesResult.put("customer.delivery.postalCode", + messages.getMessage("NotEmpty.customer.shipping.postalCode", locale)); + } + + } + + if (bindingResult.hasErrors()) { + return; + + } + + String paymentType = order.getPaymentMethodType(); + + // validate payment + if (paymentType == null) { + ServiceException serviceException = new ServiceException(ServiceException.EXCEPTION_VALIDATION, + "payment.required"); + throw serviceException; + } + + // validate shipping + if (shippingService.requiresShipping(order.getShoppingCartItems(), store) + && order.getSelectedShippingOption() == null) { + ServiceException serviceException = new ServiceException(ServiceException.EXCEPTION_VALIDATION, + "shipping.required"); + throw serviceException; + } + + // pre-validate credit card + if (PaymentType.CREDITCARD.name().equals(paymentType) + && "true".equals(coreConfiguration.getProperty("VALIDATE_CREDIT_CARD"))) { + String cco = order.getPayment().get("creditcard_card_holder"); + String cvv = order.getPayment().get("creditcard_card_cvv"); + String ccn = order.getPayment().get("creditcard_card_number"); + String ccm = order.getPayment().get("creditcard_card_expirationmonth"); + String ccd = order.getPayment().get("creditcard_card_expirationyear"); + + if (StringUtils.isBlank(cco) || StringUtils.isBlank(cvv) || StringUtils.isBlank(ccn) + || StringUtils.isBlank(ccm) || StringUtils.isBlank(ccd)) { + ObjectError error = new ObjectError("creditcard", + messages.getMessage("messages.error.creditcard", locale)); + bindingResult.addError(error); + messagesResult.put("creditcard", messages.getMessage("messages.error.creditcard", locale)); + return; + } + + CreditCardType creditCardType = null; + String cardType = order.getPayment().get("creditcard_card_type"); + + if (cardType.equalsIgnoreCase(CreditCardType.AMEX.name())) { + creditCardType = CreditCardType.AMEX; + } else if (cardType.equalsIgnoreCase(CreditCardType.VISA.name())) { + creditCardType = CreditCardType.VISA; + } else if (cardType.equalsIgnoreCase(CreditCardType.MASTERCARD.name())) { + creditCardType = CreditCardType.MASTERCARD; + } else if (cardType.equalsIgnoreCase(CreditCardType.DINERS.name())) { + creditCardType = CreditCardType.DINERS; + } else if (cardType.equalsIgnoreCase(CreditCardType.DISCOVERY.name())) { + creditCardType = CreditCardType.DISCOVERY; + } + + if (creditCardType == null) { + ServiceException serviceException = new ServiceException(ServiceException.EXCEPTION_VALIDATION, + "cc.type"); + throw serviceException; + } + + } + + } catch (ServiceException se) { + LOGGER.error("Error while commiting order", se); + throw se; + } + + } + + @Override + public com.salesmanager.shop.model.order.v0.ReadableOrderList getReadableOrderList(MerchantStore store, + Customer customer, int start, int maxCount, Language language) throws Exception { + + OrderCriteria criteria = new OrderCriteria(); + criteria.setStartIndex(start); + criteria.setMaxCount(maxCount); + criteria.setCustomerId(customer.getId()); + + return this.getReadableOrderList(criteria, store, language); + + } + + @Override + public com.salesmanager.shop.model.order.v0.ReadableOrderList getReadableOrderList(OrderCriteria criteria, + MerchantStore store) { + + try { + criteria.setLegacyPagination(false); + + OrderList orderList = orderService.getOrders(criteria, store); + + List orders = orderList.getOrders(); + com.salesmanager.shop.model.order.v0.ReadableOrderList returnList = new com.salesmanager.shop.model.order.v0.ReadableOrderList(); + + if (CollectionUtils.isEmpty(orders)) { + returnList.setRecordsTotal(0); + return returnList; + } + + List readableOrders = new ArrayList(); + for (Order order : orders) { + com.salesmanager.shop.model.order.v0.ReadableOrder readableOrder = new com.salesmanager.shop.model.order.v0.ReadableOrder(); + readableOrderPopulator.populate(order, readableOrder, null, null); + readableOrders.add(readableOrder); + + } + returnList.setOrders(readableOrders); + + returnList.setRecordsTotal(orderList.getTotalCount()); + returnList.setTotalPages(orderList.getTotalPages()); + returnList.setNumber(orderList.getOrders().size()); + returnList.setRecordsFiltered(orderList.getOrders().size()); + + return returnList; + + } catch (Exception e) { + throw new ServiceRuntimeException("Error while getting orders", e); + } + + } + + @Override + public ShippingQuote getShippingQuote(Customer customer, ShoppingCart cart, + com.salesmanager.shop.model.order.v0.PersistableOrder order, MerchantStore store, Language language) + throws Exception { + // create shipping products + List shippingProducts = shoppingCartService.createShippingProduct(cart); + + if (CollectionUtils.isEmpty(shippingProducts)) { + return null;// products are virtual + } + + Delivery delivery = new Delivery(); + + // adjust shipping and billing + if (order.isShipToBillingAdress()) { + Billing billing = customer.getBilling(); + delivery.setAddress(billing.getAddress()); + delivery.setCity(billing.getCity()); + delivery.setCompany(billing.getCompany()); + delivery.setPostalCode(billing.getPostalCode()); + delivery.setState(billing.getState()); + delivery.setCountry(billing.getCountry()); + delivery.setZone(billing.getZone()); + } else { + delivery = customer.getDelivery(); + } + + ShippingQuote quote = shippingService.getShippingQuote(cart.getId(), store, delivery, shippingProducts, + language); + + return quote; + } + + private com.salesmanager.shop.model.order.v0.ReadableOrderList populateOrderList(final OrderList orderList, + final MerchantStore store, final Language language) { + List orders = orderList.getOrders(); + com.salesmanager.shop.model.order.v0.ReadableOrderList returnList = new com.salesmanager.shop.model.order.v0.ReadableOrderList(); + if (CollectionUtils.isEmpty(orders)) { + LOGGER.info("Order list if empty..Returning empty list"); + returnList.setRecordsTotal(0); + // returnList.setMessage("No results for store code " + store); + return returnList; + } + + // ReadableOrderPopulator orderPopulator = new ReadableOrderPopulator(); + Locale locale = LocaleUtils.getLocale(language); + readableOrderPopulator.setLocale(locale); + + List readableOrders = new ArrayList(); + for (Order order : orders) { + com.salesmanager.shop.model.order.v0.ReadableOrder readableOrder = new com.salesmanager.shop.model.order.v0.ReadableOrder(); + try { + readableOrderPopulator.populate(order, readableOrder, store, language); + setOrderProductList(order, locale, store, language, readableOrder); + } catch (ConversionException ex) { + LOGGER.error("Error while converting order to order data", ex); + + } + readableOrders.add(readableOrder); + + } + + returnList.setOrders(readableOrders); + return returnList; + + } + + private void setOrderProductList(final Order order, final Locale locale, final MerchantStore store, + final Language language, final com.salesmanager.shop.model.order.v0.ReadableOrder readableOrder) + throws ConversionException { + List orderProducts = new ArrayList(); + for (OrderProduct p : order.getOrderProducts()) { + ReadableOrderProductPopulator orderProductPopulator = new ReadableOrderProductPopulator(); + orderProductPopulator.setLocale(locale); + orderProductPopulator.setProductService(productService); + orderProductPopulator.setPricingService(pricingService); + orderProductPopulator.setimageUtils(imageUtils); + ReadableOrderProduct orderProduct = new ReadableOrderProduct(); + orderProductPopulator.populate(p, orderProduct, store, language); + + // image + + // attributes + + orderProducts.add(orderProduct); + } + + readableOrder.setProducts(orderProducts); + } + + private com.salesmanager.shop.model.order.v0.ReadableOrderList getReadableOrderList(OrderCriteria criteria, + MerchantStore store, Language language) throws Exception { + + OrderList orderList = orderService.listByStore(store, criteria); + + // ReadableOrderPopulator orderPopulator = new ReadableOrderPopulator(); + Locale locale = LocaleUtils.getLocale(language); + readableOrderPopulator.setLocale(locale); + + List orders = orderList.getOrders(); + com.salesmanager.shop.model.order.v0.ReadableOrderList returnList = new com.salesmanager.shop.model.order.v0.ReadableOrderList(); + + if (CollectionUtils.isEmpty(orders)) { + returnList.setRecordsTotal(0); + // returnList.setMessage("No results for store code " + store); + return null; + } + + List readableOrders = new ArrayList(); + for (Order order : orders) { + com.salesmanager.shop.model.order.v0.ReadableOrder readableOrder = new com.salesmanager.shop.model.order.v0.ReadableOrder(); + readableOrderPopulator.populate(order, readableOrder, store, language); + readableOrders.add(readableOrder); + + } + + returnList.setRecordsTotal(orderList.getTotalCount()); + return this.populateOrderList(orderList, store, language); + + } + + @Override + public com.salesmanager.shop.model.order.v0.ReadableOrderList getReadableOrderList(MerchantStore store, int start, + int maxCount, Language language) throws Exception { + + OrderCriteria criteria = new OrderCriteria(); + criteria.setStartIndex(start); + criteria.setMaxCount(maxCount); + + return getReadableOrderList(criteria, store, language); + } + + @Override + public com.salesmanager.shop.model.order.v0.ReadableOrder getReadableOrder(Long orderId, MerchantStore store, + Language language) { + Validate.notNull(store, "MerchantStore cannot be null"); + Order modelOrder = orderService.getOrder(orderId, store); + if (modelOrder == null) { + throw new ResourceNotFoundException("Order not found with id " + orderId); + } + + com.salesmanager.shop.model.order.v0.ReadableOrder readableOrder = new com.salesmanager.shop.model.order.v0.ReadableOrder(); + + Long customerId = modelOrder.getCustomerId(); + if (customerId != null) { + ReadableCustomer readableCustomer = customerFacade.getCustomerById(customerId, store, language); + if (readableCustomer == null) { + LOGGER.warn("Customer id " + customerId + " not found in order " + orderId); + } else { + readableOrder.setCustomer(readableCustomer); + } + } + + try { + readableOrderPopulator.populate(modelOrder, readableOrder, store, language); + + // order products + List orderProducts = new ArrayList(); + for (OrderProduct p : modelOrder.getOrderProducts()) { + ReadableOrderProductPopulator orderProductPopulator = new ReadableOrderProductPopulator(); + orderProductPopulator.setProductService(productService); + orderProductPopulator.setPricingService(pricingService); + orderProductPopulator.setimageUtils(imageUtils); + + ReadableOrderProduct orderProduct = new ReadableOrderProduct(); + orderProductPopulator.populate(p, orderProduct, store, language); + orderProducts.add(orderProduct); + } + + readableOrder.setProducts(orderProducts); + } catch (Exception e) { + throw new ServiceRuntimeException("Error while getting order [" + orderId + "]"); + } + + return readableOrder; + } + + @Override + public ShippingQuote getShippingQuote(Customer customer, ShoppingCart cart, MerchantStore store, Language language) + throws Exception { + + Validate.notNull(customer, "Customer cannot be null"); + Validate.notNull(cart, "cart cannot be null"); + + // create shipping products + List shippingProducts = shoppingCartService.createShippingProduct(cart); + + if (CollectionUtils.isEmpty(shippingProducts)) { + return null;// products are virtual + } + + Delivery delivery = new Delivery(); + Billing billing = new Billing(); + //default value + billing.setCountry(store.getCountry()); + + + // adjust shipping and billing + if (customer.getDelivery() == null || StringUtils.isBlank(customer.getDelivery().getPostalCode())) { + if(customer.getBilling()!=null) { + billing = customer.getBilling(); + } + delivery.setAddress(billing.getAddress()); + delivery.setCity(billing.getCity()); + delivery.setCompany(billing.getCompany()); + delivery.setPostalCode(billing.getPostalCode()); + delivery.setState(billing.getState()); + delivery.setCountry(billing.getCountry()); + delivery.setZone(billing.getZone()); + } else { + delivery = customer.getDelivery(); + } + + ShippingQuote quote = shippingService.getShippingQuote(cart.getId(), store, delivery, shippingProducts, + language); + return quote; + } + + /** + * Process order from api + */ + @Override + public Order processOrder(com.salesmanager.shop.model.order.v1.PersistableOrder order, Customer customer, + MerchantStore store, Language language, Locale locale) throws ServiceException { + + Validate.notNull(order, "Order cannot be null"); + Validate.notNull(customer, "Customer cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + Validate.notNull(locale, "Locale cannot be null"); + + try { + + + Order modelOrder = new Order(); + persistableOrderApiPopulator.populate(order, modelOrder, store, language); + + Long shoppingCartId = order.getShoppingCartId(); + ShoppingCart cart = shoppingCartService.getById(shoppingCartId, store); + + if (cart == null) { + throw new ServiceException("Shopping cart with id " + shoppingCartId + " does not exist"); + } + + Set shoppingCartItems = cart.getLineItems(); + + List items = new ArrayList(shoppingCartItems); + + Set orderProducts = new LinkedHashSet(); + + OrderProductPopulator orderProductPopulator = new OrderProductPopulator(); + orderProductPopulator.setDigitalProductService(digitalProductService); + orderProductPopulator.setProductAttributeService(productAttributeService); + orderProductPopulator.setProductService(productService); + + for (ShoppingCartItem item : shoppingCartItems) { + OrderProduct orderProduct = new OrderProduct(); + orderProduct = orderProductPopulator.populate(item, orderProduct, store, language); + orderProduct.setOrder(modelOrder); + orderProducts.add(orderProduct); + } + + modelOrder.setOrderProducts(orderProducts); + + if (order.getAttributes() != null && order.getAttributes().size() > 0) { + Set attrs = new HashSet(); + for (com.salesmanager.shop.model.order.OrderAttribute attribute : order.getAttributes()) { + OrderAttribute attr = new OrderAttribute(); + attr.setKey(attribute.getKey()); + attr.setValue(attribute.getValue()); + attr.setOrder(modelOrder); + attrs.add(attr); + } + modelOrder.setOrderAttributes(attrs); + } + + // requires Shipping information (need a quote id calculated) + ShippingSummary shippingSummary = null; + + // get shipping quote if asked for + if (order.getShippingQuote() != null && order.getShippingQuote().longValue() > 0) { + shippingSummary = shippingQuoteService.getShippingSummary(order.getShippingQuote(), store); + if (shippingSummary != null) { + modelOrder.setShippingModuleCode(shippingSummary.getShippingModule()); + } + } + + // requires Order Totals, this needs recalculation and then compare + // total with the amount sent as part + // of process order request. If totals does not match, an error + // should be thrown. + + OrderTotalSummary orderTotalSummary = null; + + OrderSummary orderSummary = new OrderSummary(); + orderSummary.setShippingSummary(shippingSummary); + List itemsSet = new ArrayList(cart.getLineItems()); + orderSummary.setProducts(itemsSet); + + orderTotalSummary = orderService.caculateOrderTotal(orderSummary, customer, store, language); + + if (order.getPayment().getAmount() == null) { + throw new ConversionException("Requires Payment.amount"); + } + + String submitedAmount = order.getPayment().getAmount(); + + BigDecimal formattedSubmittedAmount = productPriceUtils.getAmount(submitedAmount); + + BigDecimal submitedAmountFormat = productPriceUtils.getAmount(submitedAmount); + + BigDecimal calculatedAmount = orderTotalSummary.getTotal(); + String strCalculatedTotal = calculatedAmount.toPlainString(); + + // compare both prices + if (calculatedAmount.compareTo(formattedSubmittedAmount) != 0) { + + + throw new ConversionException("Payment.amount does not match what the system has calculated " + + strCalculatedTotal + " (received " + submitedAmount + ") please recalculate the order and submit again"); + } + + modelOrder.setTotal(calculatedAmount); + List totals = orderTotalSummary.getTotals(); + Set set = new HashSet(); + + if (!CollectionUtils.isEmpty(totals)) { + for (com.salesmanager.core.model.order.OrderTotal total : totals) { + total.setOrder(modelOrder); + set.add(total); + } + } + modelOrder.setOrderTotal(set); + + PersistablePaymentPopulator paymentPopulator = new PersistablePaymentPopulator(); + paymentPopulator.setPricingService(pricingService); + Payment paymentModel = new Payment(); + paymentPopulator.populate(order.getPayment(), paymentModel, store, language); + + modelOrder.setShoppingCartCode(cart.getShoppingCartCode()); + + //lookup existing customer + //if customer exist then do not set authentication for this customer and send an instructions email + /** **/ + if(!StringUtils.isBlank(customer.getNick()) && !customer.isAnonymous()) { + if(order.getCustomerId() == null && (customerFacade.checkIfUserExists(customer.getNick(), store))) { + customer.setAnonymous(true); + customer.setNick(null); + //send email instructions + } + } + + + //order service + modelOrder = orderService.processOrder(modelOrder, customer, items, orderTotalSummary, paymentModel, store); + + // update cart + try { + cart.setOrderId(modelOrder.getId()); + shoppingCartFacade.saveOrUpdateShoppingCart(cart); + } catch (Exception e) { + LOGGER.error("Cannot delete cart " + cart.getId(), e); + } + + //email management + if ("true".equals(coreConfiguration.getProperty("ORDER_EMAIL_API"))) { + // send email + try { + + notify(modelOrder, customer, store, language, locale); + + + } catch (Exception e) { + LOGGER.error("Cannot send order confirmation email", e); + } + } + + return modelOrder; + + } catch (Exception e) { + + throw new ServiceException(e); + + } + + } + + @Async + private void notify(Order order, Customer customer, MerchantStore store, Language language, Locale locale) throws Exception { + + // send order confirmation email to customer + emailTemplatesUtils.sendOrderEmail(customer.getEmailAddress(), customer, order, locale, + language, store, coreConfiguration.getProperty("CONTEXT_PATH")); + + if (orderService.hasDownloadFiles(order)) { + emailTemplatesUtils.sendOrderDownloadEmail(customer, order, store, locale, + coreConfiguration.getProperty("CONTEXT_PATH")); + } + + // send customer credentials + + // send order confirmation email to merchant + emailTemplatesUtils.sendOrderEmail(store.getStoreEmailAddress(), customer, order, locale, + language, store, coreConfiguration.getProperty("CONTEXT_PATH")); + + + } + + @Override + public com.salesmanager.shop.model.order.v0.ReadableOrderList getCapturableOrderList(MerchantStore store, + Date startDate, Date endDate, Language language) throws Exception { + + // get all transactions for the given date + List orders = orderService.getCapturableOrders(store, startDate, endDate); + + // ReadableOrderPopulator orderPopulator = new ReadableOrderPopulator(); + Locale locale = LocaleUtils.getLocale(language); + readableOrderPopulator.setLocale(locale); + + com.salesmanager.shop.model.order.v0.ReadableOrderList returnList = new com.salesmanager.shop.model.order.v0.ReadableOrderList(); + + if (CollectionUtils.isEmpty(orders)) { + returnList.setRecordsTotal(0); + // returnList.setMessage("No results for store code " + store); + return null; + } + + List readableOrders = new ArrayList(); + for (Order order : orders) { + com.salesmanager.shop.model.order.v0.ReadableOrder readableOrder = new com.salesmanager.shop.model.order.v0.ReadableOrder(); + readableOrderPopulator.populate(order, readableOrder, store, language); + readableOrders.add(readableOrder); + + } + + returnList.setRecordsTotal(orders.size()); + returnList.setOrders(readableOrders); + + return returnList; + } + + @Override + public ReadableTransaction captureOrder(MerchantStore store, Order order, Customer customer, Language language) + throws Exception { + Transaction transactionModel = paymentService.processCapturePayment(order, customer, store); + + ReadableTransaction transaction = new ReadableTransaction(); + ReadableTransactionPopulator trxPopulator = new ReadableTransactionPopulator(); + trxPopulator.setOrderService(orderService); + trxPopulator.setPricingService(pricingService); + + trxPopulator.populate(transactionModel, transaction, store, language); + + return transaction; + + } + + @Override + public List getReadableOrderHistory(Long orderId, MerchantStore store, + Language language) { + + Order order = orderService.getOrder(orderId, store); + if (order == null) { + throw new ResourceNotFoundException( + "Order id [" + orderId + "] not found for merchand [" + store.getId() + "]"); + } + + Set historyList = order.getOrderHistory(); + List returnList = historyList.stream().map(f -> mapToReadbleOrderStatusHistory(f)) + .collect(Collectors.toList()); + return returnList; + } + + ReadableOrderStatusHistory mapToReadbleOrderStatusHistory(OrderStatusHistory source) { + ReadableOrderStatusHistory readable = new ReadableOrderStatusHistory(); + readable.setComments(source.getComments()); + readable.setDate(DateUtil.formatLongDate(source.getDateAdded())); + readable.setId(source.getId()); + readable.setOrderId(source.getOrder().getId()); + readable.setOrderStatus(source.getStatus().name()); + + return readable; + } + + @Override + public void createOrderStatus(PersistableOrderStatusHistory status, Long id, MerchantStore store) { + Validate.notNull(status, "OrderStatusHistory must not be null"); + Validate.notNull(id, "Order id must not be null"); + Validate.notNull(store, "MerchantStore must not be null"); + + // retrieve original order + Order order = orderService.getOrder(id, store); + if (order == null) { + throw new ResourceNotFoundException( + "Order with id [" + id + "] does not exist for merchant [" + store.getCode() + "]"); + } + + try { + OrderStatusHistory history = new OrderStatusHistory(); + history.setComments(status.getComments()); + history.setDateAdded(DateUtil.getDate(status.getDate())); + history.setOrder(order); + history.setStatus(status.getStatus()); + + orderService.addOrderStatusHistory(order, history); + + } catch (Exception e) { + throw new ServiceRuntimeException("An error occured while converting orderstatushistory", e); + } + + } + + @Override + public void updateOrderCustomre(Long orderId, PersistableCustomer customer, MerchantStore store) { + // TODO Auto-generated method stub + + try { + + //get order by order id + Order modelOrder = orderService.getOrder(orderId, store); + + if(modelOrder == null) { + throw new ResourceNotFoundException("Order id [" + orderId + "] not found for store [" + store.getCode() + "]"); + } + + //set customer information + modelOrder.setCustomerEmailAddress(customer.getEmailAddress()); + modelOrder.setBilling(this.convertBilling(customer.getBilling())); + modelOrder.setDelivery(this.convertDelivery(customer.getDelivery())); + + orderService.saveOrUpdate(modelOrder); + + } catch(Exception e) { + throw new ServiceRuntimeException("An error occured while updating order customer", e); + } + + } + + private Billing convertBilling(Address source) throws ServiceException { + Billing target = new Billing(); + target.setCity(source.getCity()); + target.setCompany(source.getCompany()); + target.setFirstName(source.getFirstName()); + target.setLastName(source.getLastName()); + target.setPostalCode(source.getPostalCode()); + target.setTelephone(source.getPhone()); + target.setAddress(source.getAddress()); + if(source.getCountry()!=null) { + target.setCountry(countryService.getByCode(source.getCountry())); + } + + if(source.getZone()!=null) { + target.setZone(zoneService.getByCode(source.getZone())); + } + target.setState(source.getBilstateOther()); + + return target; + } + + private Delivery convertDelivery(Address source) throws ServiceException { + Delivery target = new Delivery(); + target.setCity(source.getCity()); + target.setCompany(source.getCompany()); + target.setFirstName(source.getFirstName()); + target.setLastName(source.getLastName()); + target.setPostalCode(source.getPostalCode()); + target.setTelephone(source.getPhone()); + target.setAddress(source.getAddress()); + if(source.getCountry()!=null) { + target.setCountry(countryService.getByCode(source.getCountry())); + } + + if(source.getZone()!=null) { + target.setZone(zoneService.getByCode(source.getZone())); + } + target.setState(source.getBilstateOther()); + + return target; + } + + @Override + public TransactionType nextTransaction(Long orderId, MerchantStore store) { + + try { + + Order modelOrder = orderService.getOrder(orderId, store); + + if(modelOrder == null) { + throw new ResourceNotFoundException("Order id [" + orderId + "] not found for store [" + store.getCode() + "]"); + } + + Transaction last = transactionService.lastTransaction(modelOrder, store); + + if(last.getTransactionType().name().equals(TransactionType.AUTHORIZE.name())) { + return TransactionType.CAPTURE; + } else if(last.getTransactionType().name().equals(TransactionType.AUTHORIZECAPTURE.name())) { + return TransactionType.REFUND; + } else if(last.getTransactionType().name().equals(TransactionType.CAPTURE.name())) { + return TransactionType.REFUND; + } else if(last.getTransactionType().name().equals(TransactionType.REFUND.name())) { + return TransactionType.OK; + } else { + return TransactionType.OK; + } + + + } catch(Exception e) { + throw new ServiceRuntimeException("Error while getting last transaction for order [" + orderId + "]",e); + } + + + } + + @Override + public List listTransactions(Long orderId, MerchantStore store) { + Validate.notNull(orderId, "orderId must not be null"); + Validate.notNull(store, "MerchantStore must not be null"); + List trx = new ArrayList(); + try { + Order modelOrder = orderService.getOrder(orderId, store); + + if(modelOrder == null) { + throw new ResourceNotFoundException("Order id [" + orderId + "] not found for store [" + store.getCode() + "]"); + } + + List transactions = transactionService.listTransactions(modelOrder); + + ReadableTransaction transaction = null; + ReadableTransactionPopulator trxPopulator = null; + + for(Transaction tr : transactions) { + transaction = new ReadableTransaction(); + trxPopulator = new ReadableTransactionPopulator(); + + trxPopulator.setOrderService(orderService); + trxPopulator.setPricingService(pricingService); + + trxPopulator.populate(tr, transaction, store, store.getDefaultLanguage()); + trx.add(transaction); + } + + return trx; + + } catch(Exception e) { + LOGGER.error("Error while getting transactions for order [" + orderId + "] and store code [" + store.getCode() + "]"); + throw new ServiceRuntimeException("Error while getting transactions for order [" + orderId + "] and store code [" + store.getCode() + "]"); + } + + } + + @Override + public void updateOrderStatus(Order order, OrderStatus newStatus, MerchantStore store) { + + // make sure we are changing to different that current status + if (order.getStatus().equals(newStatus)) { + return; // we have the same status, lets just return + } + OrderStatus oldStatus = order.getStatus(); + order.setStatus(newStatus); + OrderStatusHistory history = new OrderStatusHistory(); + + history.setComments( messages.getMessage("email.order.status.changed", new String[] {oldStatus.name(), + newStatus.name()}, LocaleUtils.getLocale(store))); + history.setCustomerNotified(0); + history.setStatus(newStatus); + history.setDateAdded(new Date() ); + + try { + orderService.addOrderStatusHistory(order, history); + } catch (ServiceException e) { + e.printStackTrace(); + } + + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/search/facade/SearchFacade.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/search/facade/SearchFacade.java new file mode 100755 index 0000000000..59b651adfa --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/search/facade/SearchFacade.java @@ -0,0 +1,53 @@ +package com.salesmanager.shop.store.controller.search.facade; + +import java.util.List; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.SearchProductList; +import com.salesmanager.shop.model.catalog.SearchProductRequest; +import com.salesmanager.shop.model.entity.ValueList; + +import modules.commons.search.request.SearchItem; +import modules.commons.search.request.SearchResponse; + +/** + * Different services for searching and indexing data + * @author c.samson + * + */ +public interface SearchFacade { + + + /** + * This utility method will re-index all products in the catalogue + * @param store + * @throws Exception + */ + public void indexAllData(MerchantStore store) throws Exception; + + /** + * Produces a search request against elastic search + * @param searchRequest + * @return + * @throws Exception + */ + List search(MerchantStore store, Language language, SearchProductRequest searchRequest); + + /** + * Copy sm-core search response to a simple readable format populated with corresponding products + * @param searchResponse + * @return + */ + //public SearchProductList convertToSearchProductList(SearchResponse searchResponse, MerchantStore store, int start, int count, Language language) throws Exception; + + /** + * List of keywords / autocompletes for a given word being typed + * @param query + * @param store + * @param language + * @return + * @throws Exception + */ + ValueList autocompleteRequest(String query, MerchantStore store, Language language); +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/search/facade/SearchFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/search/facade/SearchFacadeImpl.java new file mode 100755 index 0000000000..ab9b907bf1 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/search/facade/SearchFacadeImpl.java @@ -0,0 +1,206 @@ +package com.salesmanager.shop.store.controller.search.facade; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import org.jsoup.helper.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.category.CategoryService; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.search.SearchService; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.SearchProductRequest; +import com.salesmanager.shop.model.catalog.category.ReadableCategory; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.model.entity.ValueList; +import com.salesmanager.shop.populator.catalog.ReadableCategoryPopulator; +import com.salesmanager.shop.populator.catalog.ReadableProductPopulator; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.utils.ImageFilePath; + +import modules.commons.search.request.Aggregation; +import modules.commons.search.request.SearchItem; +import modules.commons.search.request.SearchRequest; +import modules.commons.search.request.SearchResponse; + +@Service("searchFacade") +public class SearchFacadeImpl implements SearchFacade { + + private static final Logger LOGGER = LoggerFactory.getLogger(SearchFacadeImpl.class); + + @Inject + private SearchService searchService; + + @Inject + private ProductService productService; + + @Inject + private CategoryService categoryService; + + @Inject + private PricingService pricingService; + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + private final static String CATEGORY_FACET_NAME = "categories"; + private final static String MANUFACTURER_FACET_NAME = "manufacturer"; + private final static int AUTOCOMPLETE_ENTRIES_COUNT = 15; + + /** + * Index all products from the catalogue Better stop the system, remove ES + * indexex manually restart ES and run this query + */ + @Override + @Async + public void indexAllData(MerchantStore store) throws Exception { + List products = productService.listByStore(store); + + products.stream().forEach(p -> { + try { + searchService.index(store, p); + } catch (ServiceException e) { + throw new RuntimeException("Exception while indexing products", e); + } + }); + + } + + @Override + public List search(MerchantStore store, Language language, SearchProductRequest searchRequest) { + SearchResponse response = search(store, language.getCode(), searchRequest.getQuery(), searchRequest.getCount(), + searchRequest.getStart()); + return response.getItems(); + } + + private SearchResponse search(MerchantStore store, String languageCode, String query, Integer count, + Integer start) { + + Validate.notNull(query,"Search Keyword must not be null"); + Validate.notNull(languageCode, "Language cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null"); + + + try { + LOGGER.debug("Search " + query); + SearchRequest searchRequest = new SearchRequest(); + searchRequest.setLanguage(languageCode); + searchRequest.setSearchString(query); + searchRequest.setStore(store.getCode().toLowerCase()); + + + //aggregations + + //TODO add scroll + return searchService.search(store, languageCode, searchRequest, count, start); + + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + } + + private List getCategoryFacets(MerchantStore merchantStore, Language language, List facets) { + + + /** + List categoriesFacets = facets.entrySet().stream() + .filter(e -> CATEGORY_FACET_NAME.equals(e.getKey())).findFirst().map(Entry::getValue) + .orElse(Collections.emptyList()); + + if (CollectionUtils.isNotEmpty(categoriesFacets)) { + + List categoryCodes = categoriesFacets.stream().map(SearchFacet::getName) + .collect(Collectors.toList()); + + Map productCategoryCount = categoriesFacets.stream() + .collect(Collectors.toMap(SearchFacet::getKey, SearchFacet::getCount)); + + List categories = categoryService.listByCodes(merchantStore, categoryCodes, language); + return categories.stream().map(category -> convertCategoryToReadableCategory(merchantStore, language, + productCategoryCount, category)).collect(Collectors.toList()); + } else { + return Collections.emptyList(); + } + **/ + + return null; + } + + private ReadableCategory convertCategoryToReadableCategory(MerchantStore merchantStore, Language language, + Map productCategoryCount, Category category) { + ReadableCategoryPopulator populator = new ReadableCategoryPopulator(); + try { + ReadableCategory categoryProxy = populator.populate(category, new ReadableCategory(), merchantStore, + language); + Long total = productCategoryCount.get(categoryProxy.getCode()); + if (total != null) { + categoryProxy.setProductCount(total.intValue()); + } + return categoryProxy; + } catch (ConversionException e) { + throw new ConversionRuntimeException(e); + } + } + + private ReadableProduct convertProductToReadableProduct(Product product, MerchantStore merchantStore, + Language language) { + + ReadableProductPopulator populator = new ReadableProductPopulator(); + populator.setPricingService(pricingService); + populator.setimageUtils(imageUtils); + + try { + return populator.populate(product, new ReadableProduct(), merchantStore, language); + } catch (ConversionException e) { + throw new ConversionRuntimeException(e); + } + } + + @Override + public ValueList autocompleteRequest(String word, MerchantStore store, Language language) { + Validate.notNull(word,"Search Keyword must not be null"); + Validate.notNull(language, "Language cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null"); + + SearchRequest req = new SearchRequest(); + req.setLanguage(language.getCode()); + req.setStore(store.getCode().toLowerCase()); + req.setSearchString(word); + req.setLanguage(language.getCode()); + + SearchResponse response; + try { + response = searchService.searchKeywords(store, language.getCode(), req, AUTOCOMPLETE_ENTRIES_COUNT); + } catch (ServiceException e) { + throw new RuntimeException(e); + } + + + List keywords = response.getItems().stream().map(i -> i.getSuggestions()).collect(Collectors.toList()); + + ValueList valueList = new ValueList(); + valueList.setValues(keywords); + + return valueList; + + + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/security/facade/SecurityFacade.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/security/facade/SecurityFacade.java new file mode 100755 index 0000000000..be4199a3d2 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/security/facade/SecurityFacade.java @@ -0,0 +1,44 @@ +package com.salesmanager.shop.store.controller.security.facade; + +import java.util.List; +import com.salesmanager.shop.model.security.ReadablePermission; + +public interface SecurityFacade { + + /** + * Get permissions by group + * @param groups + * @return + */ + List getPermissions(List groups); + + /** + * Validates password format + * @param password + * @return + */ + public boolean validateUserPassword(final String password); + + /** + * Encode clear password + * @param password + * @return + */ + public String encodePassword(final String password); + + /** + * Validate if both passwords match + * @param modelPassword (should be encrypted) + * @param newPassword (should be clear) + * @return + */ + public boolean matchPassword(String modelPassword, String newPassword); + + /** + * + * @param password + * @param repeatPassword + * @return + */ + public boolean matchRawPasswords(String password, String repeatPassword); +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/security/facade/SecurityFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/security/facade/SecurityFacadeImpl.java new file mode 100755 index 0000000000..c73e2c851d --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/security/facade/SecurityFacadeImpl.java @@ -0,0 +1,93 @@ +package com.salesmanager.shop.store.controller.security.facade; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.inject.Inject; + +import org.jsoup.helper.Validate; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.user.GroupService; +import com.salesmanager.core.business.services.user.PermissionService; +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.model.user.PermissionCriteria; +import com.salesmanager.core.model.user.PermissionList; +import com.salesmanager.shop.model.security.ReadablePermission; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; + +@Service("securityFacade") +public class SecurityFacadeImpl implements SecurityFacade { + + private static final String USER_PASSWORD_PATTERN = "((?=.*[a-z])(?=.*\\d)(?=.*[A-Z]).{6,12})"; + + private Pattern userPasswordPattern = Pattern.compile(USER_PASSWORD_PATTERN); + + @Inject + private PermissionService permissionService; + + @Inject + private GroupService groupService; + + @Inject + private PasswordEncoder passwordEncoder; + + @SuppressWarnings({"rawtypes", "unchecked"}) + @Override + public List getPermissions(List groups) { + + List userGroups = null; + try { + userGroups = groupService.listGroupByNames(groups); + + List ids = new ArrayList(); + for (Group g : userGroups) { + ids.add(g.getId()); + } + + PermissionCriteria criteria = new PermissionCriteria(); + criteria.setGroupIds(new HashSet(ids)); + + PermissionList permissions = permissionService.listByCriteria(criteria); + throw new ServiceRuntimeException("Not implemented"); + } catch (ServiceException e) { + e.printStackTrace(); + } + + return null; + } + + @Override + public boolean validateUserPassword(String password) { + + Matcher matcher = userPasswordPattern.matcher(password); + return matcher.matches(); + } + + @Override + public String encodePassword(String password) { + return passwordEncoder.encode(password); + } + + /** + * Match non encoded to encoded + * Don't use this as a simple raw password check + */ + @Override + public boolean matchPassword(String modelPassword, String newPassword) { + return passwordEncoder.matches(newPassword, modelPassword); + } + +@Override +public boolean matchRawPasswords(String password, String repeatPassword) { + Validate.notNull(password,"password is null"); + Validate.notNull(repeatPassword,"repeat password is null"); + return password.equals(repeatPassword); +} + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/shipping/facade/ShippingFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/shipping/facade/ShippingFacadeImpl.java new file mode 100644 index 0000000000..0afa7a8819 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/shipping/facade/ShippingFacadeImpl.java @@ -0,0 +1,387 @@ +package com.salesmanager.shop.store.controller.shipping.facade; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.CollectionUtils; +import org.jsoup.helper.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.zone.ZoneService; +import com.salesmanager.core.business.services.shipping.ShippingOriginService; +import com.salesmanager.core.business.services.shipping.ShippingService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.core.model.shipping.PackageDetails; +import com.salesmanager.core.model.shipping.ShippingConfiguration; +import com.salesmanager.core.model.shipping.ShippingOrigin; +import com.salesmanager.core.model.shipping.ShippingPackageType; +import com.salesmanager.core.model.shipping.ShippingType; +import com.salesmanager.shop.model.references.PersistableAddress; +import com.salesmanager.shop.model.references.ReadableAddress; +import com.salesmanager.shop.model.references.ReadableCountry; +import com.salesmanager.shop.model.shipping.ExpeditionConfiguration; +import com.salesmanager.shop.populator.references.ReadableCountryPopulator; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.store.api.exception.OperationNotAllowedException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; + +@Service("shippingFacade") +public class ShippingFacadeImpl implements ShippingFacade { + + private static final Logger LOGGER = LoggerFactory.getLogger(ShippingFacadeImpl.class); + + @Autowired + ShippingOriginService shippingOriginService; + + @Autowired + ShippingService shippingService; + + @Autowired + CountryService countryService; + + @Autowired + ZoneService zoneService; + + + + + @Override + public ExpeditionConfiguration getExpeditionConfiguration(MerchantStore store, Language language) { + ExpeditionConfiguration expeditionConfiguration = new ExpeditionConfiguration(); + try { + + ShippingConfiguration config = getDbConfig(store); + if(config!=null) { + expeditionConfiguration.setIternationalShipping(config.getShipType()!=null && config.getShipType().equals(ShippingType.INTERNATIONAL.name())?true:false); + expeditionConfiguration.setTaxOnShipping(config.isTaxOnShipping()); + } + + List countries = shippingService.getSupportedCountries(store); + + if(!CollectionUtils.isEmpty(countries)) { + + List countryCode = countries.stream() + .sorted(Comparator.comparing(n->n.toString())) + .collect(Collectors.toList()); + + expeditionConfiguration.setShipToCountry(countryCode); + } + + } catch (ServiceException e) { + LOGGER.error("Error while getting expedition configuration", e); + throw new ServiceRuntimeException("Error while getting Expedition configuration for store[" + store.getCode() + "]", e); + } + return expeditionConfiguration; + } + + @Override + public void saveExpeditionConfiguration(ExpeditionConfiguration expedition, MerchantStore store) { + Validate.notNull(expedition, "ExpeditionConfiguration cannot be null"); + try { + + //get original configuration + ShippingConfiguration config = getDbConfig(store); + config.setTaxOnShipping(expedition.isTaxOnShipping()); + config.setShippingType(expedition.isIternationalShipping()?ShippingType.INTERNATIONAL:ShippingType.NATIONAL); + this.saveShippingConfiguration(config, store); + + shippingService.setSupportedCountries(store, expedition.getShipToCountry()); + + + } catch (ServiceException e) { + LOGGER.error("Error while getting expedition configuration", e); + throw new ServiceRuntimeException("Error while getting Expedition configuration for store[" + store.getCode() + "]", e); + } + + } + + private void saveShippingConfiguration(ShippingConfiguration config, MerchantStore store) throws ServiceRuntimeException { + try { + shippingService.saveShippingConfiguration(config, store); + } catch (ServiceException e) { + LOGGER.error("Error while saving shipping configuration", e); + throw new ServiceRuntimeException("Error while saving shipping configuration for store [" + store.getCode() + "]", e); + } + } + + @Override + public ReadableAddress getShippingOrigin(MerchantStore store) { + + ShippingOrigin o = shippingOriginService.getByStore(store); + + if(o == null) { + throw new ResourceNotFoundException("Shipping origin does not exists for store [" + store.getCode() + "]"); + } + + ReadableAddress address = new ReadableAddress(); + address.setAddress(o.getAddress()); + address.setActive(o.isActive()); + address.setCity(o.getCity()); + address.setPostalCode(o.getPostalCode()); + if(o.getCountry()!=null) { + address.setCountry(o.getCountry().getIsoCode()); + } + Zone z = o.getZone(); + if(z != null) { + address.setStateProvince(z.getCode()); + } else { + address.setStateProvince(o.getState()); + } + + return address; + } + + @Override + public void saveShippingOrigin(PersistableAddress address, MerchantStore store) { + Validate.notNull(address, "PersistableAddress cannot be null"); + try { + ShippingOrigin o = shippingOriginService.getByStore(store); + if(o == null) { + o = new ShippingOrigin(); + } + + o.setAddress(address.getAddress()); + o.setCity(address.getCity()); + o.setCountry(countryService.getByCode(address.getCountry())); + o.setMerchantStore(store); + o.setActive(address.isActive()); + o.setPostalCode(address.getPostalCode()); + + Zone zone = zoneService.getByCode(address.getStateProvince()); + if(zone == null) { + o.setState(address.getStateProvince()); + } else { + o.setZone(zone); + } + + shippingOriginService.save(o); + + } catch (ServiceException e) { + LOGGER.error("Error while getting shipping origin for country [" + address.getCountry() + "]",e); + throw new ServiceRuntimeException("Error while getting shipping origin for country [" + address.getCountry() + "]",e); + } + + + } + + private ShippingConfiguration getDbConfig(MerchantStore store) { + + try { + //get original configuration + ShippingConfiguration config = shippingService.getShippingConfiguration(store); + if(config==null) { + config = new ShippingConfiguration(); + config.setShippingType(ShippingType.INTERNATIONAL); + } + + return config; + } catch (ServiceException e) { + LOGGER.error("Error while getting expedition configuration", e); + throw new ServiceRuntimeException("Error while getting Expedition configuration for store[" + store.getCode() + "]", e); + } + + } + + @Override + public void createPackage(PackageDetails packaging, MerchantStore store) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(packaging, "PackageDetails cannot be null"); + ShippingConfiguration config = getDbConfig(store); + + if(this.packageExists(config, packaging)) { + throw new OperationNotAllowedException("Package with unique code [" + packaging.getCode() + "] already exist"); + } + + com.salesmanager.core.model.shipping.Package pack = toPackage(packaging); + + + //need to check if code exists + config.getPackages().add(pack); + this.saveShippingConfiguration(config, store); + + } + + private boolean packageExists(ShippingConfiguration configuration, PackageDetails packageDetails) { + + Validate.notNull(configuration,"ShippingConfiguration cannot be null"); + Validate.notNull(packageDetails, "PackageDetails cannot be null"); + Validate.notEmpty(packageDetails.getCode(), "PackageDetails code cannot be empty"); + + List packages = configuration.getPackages().stream().filter(p -> p.getCode().equalsIgnoreCase(packageDetails.getCode())).collect(Collectors.toList()); + + if(packages.isEmpty()) { + return false; + } else { + return true; + } + + + } + + private com.salesmanager.core.model.shipping.Package packageDetails(ShippingConfiguration configuration, String code) { + + Validate.notNull(configuration,"ShippingConfiguration cannot be null"); + Validate.notNull(code, "PackageDetails code cannot be null"); + + List packages = configuration.getPackages().stream().filter(p -> p.getCode().equalsIgnoreCase(code)).collect(Collectors.toList()); + + if(!packages.isEmpty()) { + return packages.get(0); + } else { + return null; + } + + + } + + @Override + public PackageDetails getPackage(String code, MerchantStore store) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notEmpty(code,"Packaging unique code cannot be empty"); + + ShippingConfiguration config = getDbConfig(store); + + com.salesmanager.core.model.shipping.Package p = this.packageDetails(config, code); + + if(p == null) { + throw new ResourceNotFoundException("Package with unique code [" + code + "] not found"); + } + + return toPackageDetails(p); + } + + @Override + public List listPackages(MerchantStore store) { + Validate.notNull(store, "MerchantStore cannot be null"); + ShippingConfiguration config = getDbConfig(store); + + return config.getPackages().stream().map(p -> this.toPackageDetails(p)).collect(Collectors.toList()); + + } + + @Override + public void updatePackage(String code, PackageDetails packaging, MerchantStore store) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(packaging, "PackageDetails cannot be null"); + Validate.notEmpty(code,"Packaging unique code cannot be empty"); + + ShippingConfiguration config = getDbConfig(store); + + com.salesmanager.core.model.shipping.Package p = this.packageDetails(config, code); + + if(p == null) { + throw new ResourceNotFoundException("Package with unique code [" + packaging.getCode() + "] not found"); + } + + com.salesmanager.core.model.shipping.Package pack = toPackage(packaging); + pack.setCode(code); + + //need to check if code exists + List packs = config.getPackages().stream().filter(pa -> !pa.getCode().equals(code)).collect(Collectors.toList()); + packs.add(pack); + + config.setPackages(packs); + this.saveShippingConfiguration(config, store); + + } + + @Override + public void deletePackage(String code, MerchantStore store) { + + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notEmpty(code,"Packaging unique code cannot be empty"); + + ShippingConfiguration config = getDbConfig(store); + + List packages = config.getPackages(); + + List packList = config.getPackages().stream().filter(p -> p.getCode().equalsIgnoreCase(code)).collect(Collectors.toList()); + + if(!packList.isEmpty()) { + packages.removeAll(packList); + config.setPackages(packages); + this.saveShippingConfiguration(config, store); + } + + } + + private PackageDetails toPackageDetails(com.salesmanager.core.model.shipping.Package pack) { + PackageDetails details = new PackageDetails(); + details.setCode(pack.getCode()); + details.setShippingHeight(pack.getBoxHeight()); + details.setShippingLength(pack.getBoxLength()); + details.setShippingMaxWeight(pack.getMaxWeight()); + //details.setShippingQuantity(pack.getShippingQuantity()); + details.setShippingWeight(pack.getBoxWeight()); + details.setShippingWidth(pack.getBoxWidth()); + details.setTreshold(pack.getTreshold()); + details.setType(pack.getShipPackageType().name()); + return details; + } + + private com.salesmanager.core.model.shipping.Package toPackage(PackageDetails pack) { + com.salesmanager.core.model.shipping.Package details = new com.salesmanager.core.model.shipping.Package(); + details.setCode(pack.getCode()); + details.setBoxHeight(pack.getShippingHeight()); + details.setBoxLength(pack.getShippingLength()); + details.setMaxWeight(pack.getShippingMaxWeight()); + //details.setShippingQuantity(pack.getShippingQuantity()); + details.setBoxWeight(pack.getShippingWeight()); + details.setBoxWidth(pack.getShippingWidth()); + details.setTreshold(pack.getTreshold()); + details.setShipPackageType(ShippingPackageType.valueOf(pack.getType())); + return details; + } + + @Override + public List shipToCountry(MerchantStore store, Language language) { + + + try { + List countries = shippingService.getShipToCountryList(store, language); + + List countryList = new ArrayList(); + + if(!CollectionUtils.isEmpty(countries)) { + + countryList = countries.stream() + .map(c -> { + try { + return convert(c, store, language); + } catch (ConversionException e) { + throw new ConversionRuntimeException("Error converting Country to readable country,e"); + } + }) + .sorted(Comparator.comparing(ReadableCountry::getName)) + .collect(Collectors.toList()); + + } + + return countryList; + } catch (Exception e) { + throw new ServiceRuntimeException("Error getting shipping country", e); + } + + + + + } + + ReadableCountry convert(Country country, MerchantStore store, Language lang) throws ConversionException { + ReadableCountryPopulator countryPopulator = new ReadableCountryPopulator(); + return countryPopulator.populate(country, store, lang); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/shoppingCart/facade/ShoppingCartFacade.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/shoppingCart/facade/ShoppingCartFacade.java new file mode 100755 index 0000000000..378292c6e4 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/shoppingCart/facade/ShoppingCartFacade.java @@ -0,0 +1,180 @@ +/** + * + */ +package com.salesmanager.shop.store.controller.shoppingCart.facade; + +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.shop.model.shoppingcart.PersistableShoppingCartItem; +import com.salesmanager.shop.model.shoppingcart.ReadableShoppingCart; +import com.salesmanager.shop.model.shoppingcart.ShoppingCartData; +import com.salesmanager.shop.model.shoppingcart.ShoppingCartItem; +import org.springframework.lang.Nullable; + +import java.util.List; +import java.util.Optional; + +/** + *

    Shopping cart Facade which provide abstraction layer between + * SM core module and Controller. + * Only Data Object will be exposed to controller by hiding model + * object from view.

    + * @author Umesh Awasthi + * @author Carl Samson + * @version 1.0 + * @since1.0 + * + */ + + +public interface ShoppingCartFacade { + + public ShoppingCartData addItemsToShoppingCart(ShoppingCartData shoppingCart,final ShoppingCartItem item, final MerchantStore store,final Language language,final Customer customer) throws Exception; + public ShoppingCart createCartModel(final String shoppingCartCode, final MerchantStore store,final Customer customer) throws Exception; + /** + * Method responsible for getting shopping cart from + * either session or from underlying DB. + */ + /** + * @param supportPromoCode + * @param customer + * @param store + * @param shoppingCartId + * @param language + * @return + * @throws Exception + */ + + public void deleteShoppingCart(final Long id, final MerchantStore store) throws Exception; + + public ShoppingCart getShoppingCartModel(final String shoppingCartCode, MerchantStore store) throws Exception; + public ShoppingCart getShoppingCartModel(Long id, MerchantStore store) throws Exception; + public ShoppingCart getShoppingCartModel(final Customer customer, MerchantStore store) throws Exception; + + void deleteShoppingCart(String code, MerchantStore store) throws Exception; + void saveOrUpdateShoppingCart(ShoppingCart cart) throws Exception; + + /** + * Get ShoppingCart + * This method is used by the API + * @param customer + * @param store + * @param language + * @return + * @throws Exception + */ + ReadableShoppingCart getCart(Customer customer, MerchantStore store, Language language) throws Exception; + + /** + * Modify an item to an existing cart, quantity of line item will reflect item.getQuantity + * @param cartCode + * @param item + * @param store + * @param language + * @return + * @throws Exception + */ + ReadableShoppingCart modifyCart(String cartCode, PersistableShoppingCartItem item, MerchantStore store, + Language language) throws Exception; + + /** + * Adds a promo code / coupon code to an existing code + * @param cartCode + * @param promo + * @param store + * @param language + * @return + * @throws Exception + */ + ReadableShoppingCart modifyCart(String cartCode, String promo, MerchantStore store, + Language language) throws Exception; + + /** + * Modify a list of items to an existing cart, quantity of line item will reflect item.getQuantity + * @param cartCode + * @param items + * @param store + * @param language + * @return + * @throws Exception + */ + ReadableShoppingCart modifyCartMulti(String cartCode, List items, MerchantStore store, + Language language) throws Exception; + + /** + * Add item to shopping cart + * @param item + * @param store + * @param language + */ + ReadableShoppingCart addToCart(PersistableShoppingCartItem item, MerchantStore store, + Language language); + + /** + * Removes a shopping cart item + * @param cartCode + * @param sku + * @param merchant + * @param language + * @param returnCart + * @return ReadableShoppingCart or NULL + * @throws Exception + */ + @Nullable + ReadableShoppingCart removeShoppingCartItem(String cartCode, String sku, MerchantStore merchant, Language language, boolean returnCart) throws Exception; + + /** + * Add product to ShoppingCart + * This method is used by the API + * @param customer + * @param item + * @param store + * @param language + * @return + * @throws Exception + */ + ReadableShoppingCart addToCart(Customer customer, PersistableShoppingCartItem item, MerchantStore store, Language language) throws Exception; + + /** + * Retrieves a shopping cart by ID + * @param shoppingCartId + * @param store + * @param language + * @return + * @throws Exception + */ + ReadableShoppingCart getById(Long shoppingCartId, MerchantStore store, Language language) throws Exception; + + /** + * Retrieves a shopping cart + * @param code + * @param store + * @param language + * @return + * @throws Exception + */ + ReadableShoppingCart getByCode(String code, MerchantStore store, Language language) throws Exception; + + + /** + * Set an order id to a shopping cart + * @param code + * @param orderId + * @param store + * @throws Exception + */ + void setOrderId(String code, Long orderId, MerchantStore store) throws Exception; + + + /** + * Transform cart model to readable cart + * @param cart + * @param store + * @param language + * @return + */ + ReadableShoppingCart readableCart(ShoppingCart cart, MerchantStore store, Language language); + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/shoppingCart/facade/ShoppingCartFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/shoppingCart/facade/ShoppingCartFacadeImpl.java new file mode 100755 index 0000000000..7fdc139156 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/shoppingCart/facade/ShoppingCartFacadeImpl.java @@ -0,0 +1,1164 @@ +/** + * + */ +package com.salesmanager.shop.store.controller.shoppingCart.facade; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +import javax.inject.Inject; +import javax.persistence.NoResultException; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.lang.Nullable; +import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService; +import com.salesmanager.core.business.services.shoppingcart.ShoppingCartCalculationService; +import com.salesmanager.core.business.services.shoppingcart.ShoppingCartService; +//import com.salesmanager.core.business.utils.ProductPriceUtils; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.price.FinalPrice; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.mapper.cart.ReadableShoppingCartMapper; +import com.salesmanager.shop.model.shoppingcart.CartModificationException; +import com.salesmanager.shop.model.shoppingcart.PersistableShoppingCartItem; +import com.salesmanager.shop.model.shoppingcart.ReadableShoppingCart; +import com.salesmanager.shop.model.shoppingcart.ShoppingCartAttribute; +import com.salesmanager.shop.model.shoppingcart.ShoppingCartData; +import com.salesmanager.shop.model.shoppingcart.ShoppingCartItem; +import com.salesmanager.shop.populator.shoppingCart.ShoppingCartDataPopulator; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.utils.DateUtil; +import com.salesmanager.shop.utils.ImageFilePath; + +/** + * @author Umesh Awasthi + * @author Carl Samson + * @version 3.2.0 + * @since 1.0 + */ +@Service(value = "shoppingCartFacade") +public class ShoppingCartFacadeImpl implements ShoppingCartFacade { + + private static final Logger LOG = LoggerFactory.getLogger(ShoppingCartFacadeImpl.class); + + @Inject + private ShoppingCartService shoppingCartService; + + @Inject + private ShoppingCartCalculationService shoppingCartCalculationService; + + + @Inject + private ProductService productService; + + @Inject + private PricingService pricingService; + + @Inject + private ProductAttributeService productAttributeService; + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + @Autowired + private ReadableShoppingCartMapper readableShoppingCartMapper; + + public void deleteShoppingCart(final Long id, final MerchantStore store) throws Exception { + ShoppingCart cart = shoppingCartService.getById(id, store); + if (cart != null) { + shoppingCartService.deleteCart(cart); + } + } + + @Override + public void deleteShoppingCart(final String code, final MerchantStore store) throws Exception { + ShoppingCart cart = shoppingCartService.getByCode(code, store); + if (cart != null) { + shoppingCartService.deleteCart(cart); + } + } + + // @Override + // REMOVE + public ShoppingCartData addItemsToShoppingCart(final ShoppingCartData shoppingCartData, final ShoppingCartItem item, + final MerchantStore store, final Language language, final Customer customer) throws Exception { + + ShoppingCart cartModel = null; + + /** + * Sometimes a user logs in and a shopping cart is present in db + * (shoppingCartData but ui has no cookie with shopping cart code so the cart + * code will have to be added to the item in order to process add to cart + * normally + */ + if (shoppingCartData != null && StringUtils.isBlank(item.getCode())) { + item.setCode(shoppingCartData.getCode()); + } + + if (!StringUtils.isBlank(item.getCode())) { + // get it from the db + cartModel = getShoppingCartModel(item.getCode(), store); + if (cartModel == null) { + cartModel = createCartModel(shoppingCartData.getCode(), store, customer); + } + + } + + if (cartModel == null) { + + final String shoppingCartCode = StringUtils.isNotBlank(shoppingCartData.getCode()) + ? shoppingCartData.getCode() + : null; + cartModel = createCartModel(shoppingCartCode, store, customer); + + } + com.salesmanager.core.model.shoppingcart.ShoppingCartItem shoppingCartItem = createCartItem(cartModel, item, + store); + + boolean duplicateFound = false; + if (CollectionUtils.isEmpty(item.getShoppingCartAttributes())) {// increment quantity + // get duplicate item from the cart + Set cartModelItems = cartModel.getLineItems(); + for (com.salesmanager.core.model.shoppingcart.ShoppingCartItem cartItem : cartModelItems) { + if (cartItem.getProduct().getId().longValue() == shoppingCartItem.getProduct().getId().longValue()) { + if (CollectionUtils.isEmpty(cartItem.getAttributes())) { + if (!duplicateFound) { + if (!shoppingCartItem.isProductVirtual()) { + cartItem.setQuantity(cartItem.getQuantity() + shoppingCartItem.getQuantity()); + } + duplicateFound = true; + break; + } + } + } + } + } + + if (!duplicateFound) { + cartModel.getLineItems().add(shoppingCartItem); + } + + /** Update cart in database with line items **/ + shoppingCartService.saveOrUpdate(cartModel); + + // refresh cart + cartModel = shoppingCartService.getById(cartModel.getId(), store); + + shoppingCartCalculationService.calculate(cartModel, store, language); + + ShoppingCartDataPopulator shoppingCartDataPopulator = new ShoppingCartDataPopulator(); + shoppingCartDataPopulator.setShoppingCartCalculationService(shoppingCartCalculationService); + shoppingCartDataPopulator.setPricingService(pricingService); + shoppingCartDataPopulator.setimageUtils(imageUtils); + + return shoppingCartDataPopulator.populate(cartModel, store, language); + } + + private com.salesmanager.core.model.shoppingcart.ShoppingCartItem createCartItem(final ShoppingCart cartModel, + final ShoppingCartItem shoppingCartItem, final MerchantStore store) throws Exception { + + Product product = productService.getBySku(shoppingCartItem.getSku(), store, store.getDefaultLanguage()); + + if (product == null) { + throw new Exception("Item with sku " + shoppingCartItem.getSku() + " does not exist"); + } + + if (product.getMerchantStore().getId().intValue() != store.getId().intValue()) { + throw new Exception( + "Item with sku " + shoppingCartItem.getSku() + " does not belong to merchant " + store.getId()); + } + + /** + * Check if product quantity is 0 Check if product is available Check if date + * available <= now + */ + + Set availabilities = product.getAvailabilities(); + if (availabilities == null) { + + throw new Exception("Item with id " + product.getId() + " is not properly configured"); + + } + + for (ProductAvailability availability : availabilities) { + if (availability.getProductQuantity() == null || availability.getProductQuantity().intValue() == 0) { + throw new Exception("Item with id " + product.getId() + " is not available"); + } + } + + if (!product.isAvailable()) { + throw new Exception("Item with id " + product.getId() + " is not available"); + } + + if (!DateUtil.dateBeforeEqualsDate(product.getDateAvailable(), new Date())) { + throw new Exception("Item with id " + product.getId() + " is not available"); + } + + com.salesmanager.core.model.shoppingcart.ShoppingCartItem item = shoppingCartService + .populateShoppingCartItem(product, store); + + item.setQuantity(shoppingCartItem.getQuantity()); + item.setShoppingCart(cartModel); + + // attributes + List cartAttributes = shoppingCartItem.getShoppingCartAttributes(); + if (!CollectionUtils.isEmpty(cartAttributes)) { + for (ShoppingCartAttribute attribute : cartAttributes) { + ProductAttribute productAttribute = productAttributeService.getById(attribute.getAttributeId()); + if (productAttribute != null + && productAttribute.getProduct().getId().longValue() == product.getId().longValue()) { + com.salesmanager.core.model.shoppingcart.ShoppingCartAttributeItem attributeItem = new com.salesmanager.core.model.shoppingcart.ShoppingCartAttributeItem( + item, productAttribute); + + item.addAttributes(attributeItem); + } + } + } + return item; + + } + + // KEEP -- ENTRY + private com.salesmanager.core.model.shoppingcart.ShoppingCartItem createCartItem(ShoppingCart cartModel, + PersistableShoppingCartItem shoppingCartItem, MerchantStore store) throws Exception { + + // USE Product sku + Product product = null; + + product = productService.getBySku(shoppingCartItem.getProduct(), store, store.getDefaultLanguage());// todo use + // language + // from api + // request + if (product == null) { + throw new ResourceNotFoundException( + "Product with sku " + shoppingCartItem.getProduct() + " does not exist"); + } + + if (product.getMerchantStore().getId().intValue() != store.getId().intValue()) { + throw new ResourceNotFoundException( + "Item with id " + shoppingCartItem.getProduct() + " does not belong to merchant " + store.getId()); + } + + if (!product.isAvailable()) { + throw new Exception("Product with sku " + product.getSku() + " is not available"); + } + + if (!DateUtil.dateBeforeEqualsDate(product.getDateAvailable(), new Date())) { + throw new Exception("Item with sku " + product.getSku() + " is not available"); + } + + Set availabilities = product.getAvailabilities(); + + ProductVariant instance = null; + if (CollectionUtils.isNotEmpty(product.getVariants())) { + instance = product.getVariants().iterator().next(); + Set instanceAvailabilities = instance.getAvailabilities(); + if(!CollectionUtils.isEmpty(instanceAvailabilities)) { + availabilities = instanceAvailabilities; + } + + } + + if (CollectionUtils.isEmpty(availabilities)) { + throw new Exception( + "Item with id " + product.getId() + " is not properly configured. It contains no inventory"); + } + + //todo filter sku and store + for (ProductAvailability availability : availabilities) { + if (availability.getProductQuantity() == null || availability.getProductQuantity().intValue() == 0) { + throw new Exception("Product with id " + product.getId() + " is not available"); + } + } + + /** + * Check if product quantity is 0 Check if product is available Check if date + * available <= now + */ + + // use a mapper + com.salesmanager.core.model.shoppingcart.ShoppingCartItem item = shoppingCartService + .populateShoppingCartItem(product, store); + + item.setQuantity(shoppingCartItem.getQuantity()); + item.setShoppingCart(cartModel); + item.setSku(product.getSku()); + + if (instance != null) { + item.setVariant(instance.getId()); + } + + // set attributes + List attributes = shoppingCartItem + .getAttributes(); + if (!CollectionUtils.isEmpty(attributes)) { + for (com.salesmanager.shop.model.catalog.product.attribute.ProductAttribute attribute : attributes) { + + ProductAttribute productAttribute = productAttributeService.getById(attribute.getId()); + + if (productAttribute != null + && productAttribute.getProduct().getId().longValue() == product.getId().longValue()) { + + com.salesmanager.core.model.shoppingcart.ShoppingCartAttributeItem attributeItem = new com.salesmanager.core.model.shoppingcart.ShoppingCartAttributeItem( + item, productAttribute); + + item.addAttributes(attributeItem); + } + } + } + + return item; + } + + // used for api + private List createCartItems(ShoppingCart cartModel, + List shoppingCartItems, MerchantStore store) throws Exception { + + List productSkus = shoppingCartItems.stream().map(s -> s.getProduct()).collect(Collectors.toList()); + + List products = productSkus.stream().map(p -> this.fetchProduct(p, store, store.getDefaultLanguage())) + .collect(Collectors.toList()); + + if (products == null || products.size() != shoppingCartItems.size()) { + LOG.warn("----------------------- Items with in id-list " + productSkus + " does not exist"); + throw new ResourceNotFoundException("Item with skus " + productSkus + " does not exist"); + } + + List wrongStoreProducts = products.stream().filter(p -> p.getMerchantStore().getId() != store.getId()) + .collect(Collectors.toList()); + if (wrongStoreProducts.size() > 0) { + throw new ResourceNotFoundException("One or more of the items with id's " + + wrongStoreProducts.stream().map(s -> Long.valueOf(s.getId())).collect(Collectors.toList()) + + " does not belong to merchant " + store.getId()); + } + + List items = new ArrayList<>(); + + for (Product p : products) { + com.salesmanager.core.model.shoppingcart.ShoppingCartItem item = shoppingCartService + .populateShoppingCartItem(p, store); + Optional oShoppingCartItem = shoppingCartItems.stream() + .filter(i -> i.getProduct().equals(p.getSku())).findFirst(); + if (!oShoppingCartItem.isPresent()) { + // Should never happen if not something is updated in realtime or user has item + // in local storage and add it long time after to cart! + LOG.warn("Missing shoppingCartItem for product " + p.getSku() + " ( " + p.getId() + " )"); + continue; + } + PersistableShoppingCartItem shoppingCartItem = oShoppingCartItem.get(); + item.setQuantity(shoppingCartItem.getQuantity()); + item.setShoppingCart(cartModel); + + /** + * Check if product is available Check if product quantity is 0 Check if date + * available <= now + */ + if (shoppingCartItem.getQuantity() > 0 && !p.isAvailable()) { + throw new Exception("Item with id " + p.getId() + " is not available"); + } + + Set availabilities = p.getAvailabilities(); + if (availabilities == null) { + throw new Exception("Item with id " + p.getId() + " is not properly configured"); + } + + for (ProductAvailability availability : availabilities) { + if (shoppingCartItem.getQuantity() > 0 && availability.getProductQuantity() == null || availability.getProductQuantity().intValue() == 0) { + throw new Exception("Item with id " + p.getId() + " is not available"); + } + } + + if (!DateUtil.dateBeforeEqualsDate(p.getDateAvailable(), new Date())) { + throw new Exception("Item with id " + p.getId() + " is not available"); + } + // end qty & availablility checks + + // set attributes + List attributes = shoppingCartItem + .getAttributes(); + if (!CollectionUtils.isEmpty(attributes)) { + for (com.salesmanager.shop.model.catalog.product.attribute.ProductAttribute attribute : attributes) { + + ProductAttribute productAttribute = productAttributeService.getById(attribute.getId()); + + if (productAttribute != null + && productAttribute.getProduct().getId().longValue() == p.getId().longValue()) { + + com.salesmanager.core.model.shoppingcart.ShoppingCartAttributeItem attributeItem = new com.salesmanager.core.model.shoppingcart.ShoppingCartAttributeItem( + item, productAttribute); + + item.addAttributes(attributeItem); + } + } + } + items.add(item); + } + + return items; + } + + private Product fetchProduct(String sku, MerchantStore store, Language language) { + try { + return productService.getBySku(sku, store, language); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + } + + @Override + public ShoppingCart createCartModel(final String shoppingCartCode, final MerchantStore store, + final Customer customer) throws Exception { + final Long CustomerId = customer != null ? customer.getId() : null; + ShoppingCart cartModel = new ShoppingCart(); + if (StringUtils.isNotBlank(shoppingCartCode)) { + cartModel.setShoppingCartCode(shoppingCartCode); + } else { + cartModel.setShoppingCartCode(uniqueShoppingCartCode()); + } + + cartModel.setMerchantStore(store); + if (CustomerId != null) { + cartModel.setCustomerId(CustomerId); + } + shoppingCartService.create(cartModel); + return cartModel; + } + + private com.salesmanager.core.model.shoppingcart.ShoppingCartItem getEntryToUpdate(final long entryId, + final ShoppingCart cartModel) { + if (CollectionUtils.isNotEmpty(cartModel.getLineItems())) { + for (com.salesmanager.core.model.shoppingcart.ShoppingCartItem shoppingCartItem : cartModel + .getLineItems()) { + if (shoppingCartItem.getId().longValue() == entryId) { + LOG.info("Found line item for given entry id: " + entryId); + return shoppingCartItem; + + } + } + } + LOG.info("Unable to find any entry for given Id: " + entryId); + return null; + } + + private Object getKeyValue(final String key) { + ServletRequestAttributes reqAttr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); + return reqAttr.getRequest().getAttribute(key); + } + + // @Override + // DELETE + public ShoppingCartData getShoppingCartData(final Customer customer, final MerchantStore store, + final String shoppingCartId, Language language) throws Exception { + + ShoppingCart cart = null; + try { + if (customer != null) { + LOG.info("Reteriving customer shopping cart..."); + cart = shoppingCartService.getShoppingCart(customer, store); + + } + + else { + if (StringUtils.isNotBlank(shoppingCartId) && cart == null) { + cart = shoppingCartService.getByCode(shoppingCartId, store); + } + + } + + } catch (ServiceException ex) { + LOG.error("Error while retriving cart from customer", ex); + } catch (NoResultException nre) { + // nothing + } + + if (cart == null) { + return null; + } + + // if cart has been completed return null + if (cart.getOrderId() != null && cart.getOrderId().longValue() > 0) { + if (StringUtils.isNotBlank(shoppingCartId) && !(shoppingCartId.equals(cart.getShoppingCartCode()))) { + cart = shoppingCartService.getByCode(shoppingCartId, store); + } else { + return null; + } + } + + LOG.info("Cart model found."); + + ShoppingCartDataPopulator shoppingCartDataPopulator = new ShoppingCartDataPopulator(); + shoppingCartDataPopulator.setShoppingCartCalculationService(shoppingCartCalculationService); + shoppingCartDataPopulator.setPricingService(pricingService); + shoppingCartDataPopulator.setimageUtils(imageUtils); + + MerchantStore merchantStore = (MerchantStore) getKeyValue(Constants.MERCHANT_STORE); + + ShoppingCartData shoppingCartData = shoppingCartDataPopulator.populate(cart, merchantStore, language); + + return shoppingCartData; + + } + + // @Override + public ShoppingCartData getShoppingCartData(ShoppingCart shoppingCartModel, Language language) throws Exception { + + Validate.notNull(shoppingCartModel, "Shopping Cart cannot be null"); + + ShoppingCartDataPopulator shoppingCartDataPopulator = new ShoppingCartDataPopulator(); + shoppingCartDataPopulator.setShoppingCartCalculationService(shoppingCartCalculationService); + shoppingCartDataPopulator.setPricingService(pricingService); + shoppingCartDataPopulator.setimageUtils(imageUtils); + // Language language = (Language) getKeyValue( Constants.LANGUAGE ); + MerchantStore merchantStore = (MerchantStore) getKeyValue(Constants.MERCHANT_STORE); + return shoppingCartDataPopulator.populate(shoppingCartModel, merchantStore, language); + } + + // @Override + // DELETE + public ShoppingCartData removeCartItem(final Long itemID, final String cartId, final MerchantStore store, + final Language language) throws Exception { + if (StringUtils.isNotBlank(cartId)) { + + ShoppingCart cartModel = getCartModel(cartId, store); + if (cartModel != null) { + if (CollectionUtils.isNotEmpty(cartModel.getLineItems())) { + Set shoppingCartItemSet = new HashSet(); + for (com.salesmanager.core.model.shoppingcart.ShoppingCartItem shoppingCartItem : cartModel + .getLineItems()) { + if (shoppingCartItem.getId().longValue() == itemID.longValue()) { + shoppingCartService.deleteShoppingCartItem(itemID); + } else { + shoppingCartItemSet.add(shoppingCartItem); + } + } + + cartModel.setLineItems(shoppingCartItemSet); + + ShoppingCartDataPopulator shoppingCartDataPopulator = new ShoppingCartDataPopulator(); + shoppingCartDataPopulator.setShoppingCartCalculationService(shoppingCartCalculationService); + shoppingCartDataPopulator.setPricingService(pricingService); + shoppingCartDataPopulator.setimageUtils(imageUtils); + return shoppingCartDataPopulator.populate(cartModel, store, language); + + } + } + } + return null; + } + + // @Override + // DELETE + public ShoppingCartData updateCartItem(final Long itemID, final String cartId, final long newQuantity, + final MerchantStore store, final Language language) throws Exception { + if (newQuantity < 1) { + throw new CartModificationException("Quantity must not be less than one"); + } + if (StringUtils.isNotBlank(cartId)) { + ShoppingCart cartModel = getCartModel(cartId, store); + if (cartModel != null) { + com.salesmanager.core.model.shoppingcart.ShoppingCartItem entryToUpdate = getEntryToUpdate( + itemID.longValue(), cartModel); + + if (entryToUpdate == null) { + throw new CartModificationException("Unknown entry number."); + } + + entryToUpdate.getProduct(); + + LOG.info("Updating cart entry quantity to" + newQuantity); + entryToUpdate.setQuantity((int) newQuantity); + List productAttributes = new ArrayList(); + productAttributes.addAll(entryToUpdate.getProduct().getAttributes()); + final FinalPrice finalPrice = pricingService.calculateProductPrice(entryToUpdate.getProduct(), + productAttributes); + entryToUpdate.setItemPrice(finalPrice.getFinalPrice()); + shoppingCartService.saveOrUpdate(cartModel); + + LOG.info("Cart entry updated with desired quantity"); + ShoppingCartDataPopulator shoppingCartDataPopulator = new ShoppingCartDataPopulator(); + shoppingCartDataPopulator.setShoppingCartCalculationService(shoppingCartCalculationService); + shoppingCartDataPopulator.setPricingService(pricingService); + shoppingCartDataPopulator.setimageUtils(imageUtils); + return shoppingCartDataPopulator.populate(cartModel, store, language); + + } + } + return null; + } + + // TODO promoCode request parameter + // @Override + // DELETE + public ShoppingCartData updateCartItems(Optional promoCode, final List shoppingCartItems, + final MerchantStore store, final Language language) throws Exception { + + Validate.notEmpty(shoppingCartItems, "shoppingCartItems null or empty"); + ShoppingCart cartModel = null; + Set cartItems = new HashSet(); + for (ShoppingCartItem item : shoppingCartItems) { + + if (item.getQuantity() < 1) { + throw new CartModificationException("Quantity must not be less than one"); + } + + if (cartModel == null) { + cartModel = getCartModel(item.getCode(), store); + } + + com.salesmanager.core.model.shoppingcart.ShoppingCartItem entryToUpdate = getEntryToUpdate(item.getId(), + cartModel); + + if (entryToUpdate == null) { + throw new CartModificationException("Unknown entry number."); + } + + entryToUpdate.getProduct(); + + LOG.info("Updating cart entry quantity to" + item.getQuantity()); + entryToUpdate.setQuantity((int) item.getQuantity()); + + List productAttributes = new ArrayList(); + productAttributes.addAll(entryToUpdate.getProduct().getAttributes()); + + final FinalPrice finalPrice = pricingService.calculateProductPrice(entryToUpdate.getProduct(), + productAttributes); + entryToUpdate.setItemPrice(finalPrice.getFinalPrice()); + + cartItems.add(entryToUpdate); + + } + + cartModel.setPromoCode(null); + if (promoCode.isPresent()) { + cartModel.setPromoCode(promoCode.get()); + cartModel.setPromoAdded(new Date()); + } + + cartModel.setLineItems(cartItems); + shoppingCartService.saveOrUpdate(cartModel); + + LOG.info("Cart entry updated with desired quantity"); + ShoppingCartDataPopulator shoppingCartDataPopulator = new ShoppingCartDataPopulator(); + shoppingCartDataPopulator.setShoppingCartCalculationService(shoppingCartCalculationService); + shoppingCartDataPopulator.setPricingService(pricingService); + shoppingCartDataPopulator.setimageUtils(imageUtils); + return shoppingCartDataPopulator.populate(cartModel, store, language); + + } + + private ShoppingCart getCartModel(final String cartId, final MerchantStore store) { + if (StringUtils.isNotBlank(cartId)) { + try { + return shoppingCartService.getByCode(cartId, store); + } catch (ServiceException e) { + LOG.error("unable to find any cart asscoiated with this Id: " + cartId); + LOG.error("error while fetching cart model...", e); + return null; + } catch (NoResultException nre) { + // nothing + } + + } + return null; + } + + // @Override + // DELETE + public ShoppingCartData getShoppingCartData(String code, MerchantStore store, Language language) { + try { + ShoppingCart cartModel = shoppingCartService.getByCode(code, store); + if (cartModel != null) { + + ShoppingCartData cart = getShoppingCartData(cartModel, language); + return cart; + } + } catch (NoResultException nre) { + // nothing + + } catch (Exception e) { + LOG.error("Cannot retrieve cart code " + code, e); + } + + return null; + } + + @Override + public ShoppingCart getShoppingCartModel(String shoppingCartCode, MerchantStore store) throws Exception { + return shoppingCartService.getByCode(shoppingCartCode, store); + } + + @Override + public ShoppingCart getShoppingCartModel(Customer customer, MerchantStore store) throws Exception { + return shoppingCartService.getShoppingCart(customer, store); + } + + @Override + public void saveOrUpdateShoppingCart(ShoppingCart cart) throws Exception { + shoppingCartService.saveOrUpdate(cart); + + } + + @Override + public ReadableShoppingCart getCart(Customer customer, MerchantStore store, Language language) throws Exception { + + Validate.notNull(customer, "Customer cannot be null"); + Validate.notNull(customer.getId(), "Customer.id cannot be null or empty"); + + // Check if customer has an existing shopping cart + ShoppingCart cartModel = shoppingCartService.getShoppingCart(customer, store); + + if (cartModel == null) { + return null; + } + + shoppingCartCalculationService.calculate(cartModel, store, language); + + ReadableShoppingCart readableCart = new ReadableShoppingCart(); + readableCart = readableShoppingCartMapper.convert(cartModel, store, language); + + return readableCart; + } + + @Override + // KEEP ** ENTRY POINT ** + public ReadableShoppingCart addToCart(PersistableShoppingCartItem item, MerchantStore store, Language language) { + + Validate.notNull(item, "PersistableShoppingCartItem cannot be null"); + + // if cart does not exist create a new one + + ShoppingCart cartModel = new ShoppingCart(); + cartModel.setMerchantStore(store); + cartModel.setShoppingCartCode(uniqueShoppingCartCode()); + + if (!StringUtils.isBlank(item.getPromoCode())) { + cartModel.setPromoCode(item.getPromoCode()); + cartModel.setPromoAdded(new Date()); + } + + try { + return readableShoppingCart(cartModel, item, store, language); + } catch (Exception e) { + if (e instanceof ResourceNotFoundException) { + throw (ResourceNotFoundException) e; + } else { + throw new ServiceRuntimeException(e.getMessage(),e); + } + } + } + + @Override + // KEEP + public @Nullable ReadableShoppingCart removeShoppingCartItem(String cartCode, String sku, + MerchantStore merchant, Language language, boolean returnCart) throws Exception { + Validate.notNull(cartCode, "Shopping cart code must not be null"); + Validate.notNull(sku, "product sku must not be null"); + Validate.notNull(merchant, "MerchantStore must not be null"); + + // get cart + ShoppingCart cart = getCartModel(cartCode, merchant); + + if (cart == null) { + throw new ResourceNotFoundException("Cart code [ " + cartCode + " ] not found"); + } + + Set items = new HashSet(); + com.salesmanager.core.model.shoppingcart.ShoppingCartItem itemToDelete = null; + for (com.salesmanager.core.model.shoppingcart.ShoppingCartItem shoppingCartItem : cart.getLineItems()) { + if (shoppingCartItem.getProduct().getSku().equals(sku)) { + // get cart item + itemToDelete = getEntryToUpdate(shoppingCartItem.getId(), cart); + + // break; + + } else { + items.add(shoppingCartItem); + } + } + // delete item + if (itemToDelete != null) { + shoppingCartService.deleteShoppingCartItem(itemToDelete.getId()); + } + + // remaining items + if (items.size() > 0) { + cart.setLineItems(items); + } else { + cart.getLineItems().clear(); + } + + shoppingCartService.saveOrUpdate(cart);// update cart with remaining items + if (items.size() > 0 & returnCart) { + return this.getByCode(cartCode, merchant, language); + } + return null; + } + + // KEEP + private ReadableShoppingCart readableShoppingCart(ShoppingCart cartModel, PersistableShoppingCartItem item, + MerchantStore store, Language language) throws Exception { + + com.salesmanager.core.model.shoppingcart.ShoppingCartItem itemModel = createCartItem(cartModel, item, store); + + // need to check if the item is already in the cart + boolean duplicateFound = false; + // only if item has no attributes + if (CollectionUtils.isEmpty(item.getAttributes())) {// increment quantity + // get duplicate item from the cart + Set cartModelItems = cartModel.getLineItems(); + for (com.salesmanager.core.model.shoppingcart.ShoppingCartItem cartItem : cartModelItems) { + if (cartItem.getProduct().getSku().equals(item.getProduct())) { + if (CollectionUtils.isEmpty(cartItem.getAttributes())) { + if (!duplicateFound) { + if (!itemModel.isProductVirtual()) { + cartItem.setQuantity(cartItem.getQuantity() + item.getQuantity()); + } + duplicateFound = true; + break; + } + } + } + } + } + + if (!duplicateFound) { + cartModel.getLineItems().add(itemModel); + } + + saveShoppingCart(cartModel); + + // refresh cart + cartModel = shoppingCartService.getById(cartModel.getId(), store); + + shoppingCartCalculationService.calculate(cartModel, store, language); + return readableShoppingCartMapper.convert(cartModel, store, language); + + } + + @Override + // KEEP + public ReadableShoppingCart readableCart(ShoppingCart cart, MerchantStore store, Language language) { + return readableShoppingCartMapper.convert(cart, store, language); + + } + + private ReadableShoppingCart modifyCart(ShoppingCart cartModel, PersistableShoppingCartItem item, + MerchantStore store, Language language) throws Exception { + + com.salesmanager.core.model.shoppingcart.ShoppingCartItem itemModel = createCartItem(cartModel, item, store); + + boolean itemModified = false; + // check if existing product + Set items = cartModel.getLineItems(); + if (!CollectionUtils.isEmpty(items)) { + Set newItems = new HashSet(); + Set removeItems = new HashSet(); + for (com.salesmanager.core.model.shoppingcart.ShoppingCartItem anItem : items) {// take care of existing + // product + if (itemModel.getProduct().getId().longValue() == anItem.getProduct().getId()) { + if (item.getQuantity() == 0) { + // left aside item to be removed + // don't add it to new list of item + removeItems.add(anItem); + } else { + // new quantity + anItem.setQuantity(item.getQuantity()); + newItems.add(anItem); + } + itemModified = true; + } else { + newItems.add(anItem); + } + } + + if (!removeItems.isEmpty()) { + for (com.salesmanager.core.model.shoppingcart.ShoppingCartItem emptyItem : removeItems) { + shoppingCartService.deleteShoppingCartItem(emptyItem.getId()); + } + + } + + if (!itemModified) { + newItems.add(itemModel); + } + + if (newItems.isEmpty()) { + newItems = null; + } + + cartModel.setLineItems(newItems); + } else { + // new item + if (item.getQuantity() > 0) { + cartModel.getLineItems().add(itemModel); + } + } + + // if cart items are null just return cart with no items + + // promo code added to the cart but no promo cart exists + if (!StringUtils.isBlank(item.getPromoCode()) && StringUtils.isBlank(cartModel.getPromoCode())) { + cartModel.setPromoCode(item.getPromoCode()); + cartModel.setPromoAdded(new Date()); + } + + saveShoppingCart(cartModel); + + // refresh cart + cartModel = shoppingCartService.getById(cartModel.getId(), store); + + if (cartModel == null) { + return null; + } + + shoppingCartCalculationService.calculate(cartModel, store, language); + + ReadableShoppingCart readableCart = new ReadableShoppingCart(); + readableCart = readableShoppingCartMapper.convert(cartModel, store, language); + + return readableCart; + + } + + /** + * Update cart based on the Items coming in with cartItems, Items not in + * incoming will not be affected, Items with Qty set to 0 will be removed from + * cart + * + * @param cartModel + * @param cartItems + * @param store + * @param language + * @return + * @throws Exception + */ + // KEEP + private ReadableShoppingCart modifyCartMulti(ShoppingCart cartModel, List cartItems, + MerchantStore store, Language language) throws Exception { + + int itemUpdatedCnt = 0; + List inCartItemList = createCartItems(cartModel, + cartItems, store); + + Set existingItems = cartModel.getLineItems(); + // loop over incoming items since they drive changes + for (com.salesmanager.core.model.shoppingcart.ShoppingCartItem newItemValue : inCartItemList) { + + // check that item exist in persisted cart + Optional oOldItem = existingItems.stream() + .filter(i -> i.getSku().equals(newItemValue.getSku()) + + ).findFirst(); + + if (oOldItem.isPresent()) { + // update of existing cartItem + com.salesmanager.core.model.shoppingcart.ShoppingCartItem oldCartItem = oOldItem.get(); + if (oldCartItem.getQuantity().intValue() == newItemValue.getQuantity()) { + // this is unchanged + continue; + } + if (newItemValue.getQuantity() == 0) { + // remove from cart + shoppingCartService.deleteShoppingCartItem(oldCartItem.getId()); + cartModel.getLineItems().remove(oldCartItem); + ++itemUpdatedCnt; + continue; + } + // update qty + oldCartItem.setQuantity(newItemValue.getQuantity()); + ++itemUpdatedCnt; + } else { + // addition of new item + cartModel.getLineItems().add(newItemValue); + ++itemUpdatedCnt; + } + } + // at the moment we expect that some change have been done + saveShoppingCart(cartModel); + + // refresh cart + cartModel = shoppingCartService.getById(cartModel.getId(), store); + + if (cartModel == null) { + return null; + } + + shoppingCartCalculationService.calculate(cartModel, store, language); + + return readableShoppingCartMapper.convert(cartModel, store, language); + + } + + @Override + // KEEP + public ReadableShoppingCart addToCart(Customer customer, PersistableShoppingCartItem item, MerchantStore store, + Language language) throws Exception { + + Validate.notNull(customer, "Customer cannot be null"); + Validate.notNull(customer.getId(), "Customer.id cannot be null or empty"); + + ShoppingCart cartModel = shoppingCartService.getShoppingCart(customer, store); + + // if cart does not exist create a new one + if (cartModel == null) { + cartModel = new ShoppingCart(); + cartModel.setCustomerId(customer.getId()); + cartModel.setMerchantStore(store); + cartModel.setShoppingCartCode(uniqueShoppingCartCode()); + } + + return readableShoppingCart(cartModel, item, store, language); + } + + @Override + // KEEP + public ReadableShoppingCart modifyCart(String cartCode, PersistableShoppingCartItem item, MerchantStore store, + Language language) throws Exception { + + Validate.notNull(cartCode, "String cart code cannot be null"); + Validate.notNull(item, "PersistableShoppingCartItem cannot be null"); + + ShoppingCart cartModel = getCartModel(cartCode, store); + if (cartModel == null) { + throw new ResourceNotFoundException("Cart code [" + cartCode + "] not found"); + } + + return modifyCart(cartModel, item, store, language); + } + + @Override + // KEEP + public ReadableShoppingCart modifyCartMulti(String cartCode, List items, + MerchantStore store, Language language) throws Exception { + Validate.notNull(cartCode, "String cart code cannot be null"); + Validate.notNull(items, "PersistableShoppingCartItem cannot be null"); + + ShoppingCart cartModel = this.getCartModel(cartCode, store); + if (cartModel == null) { + throw new IllegalArgumentException("Cart code not valid"); + } + + return modifyCartMulti(cartModel, items, store, language); + } + + private void saveShoppingCart(ShoppingCart shoppingCart) throws Exception { + shoppingCartService.save(shoppingCart); + } + + private String uniqueShoppingCartCode() { + return UUID.randomUUID().toString().replaceAll("-", ""); + } + + @Override + public ReadableShoppingCart getById(Long shoppingCartId, MerchantStore store, Language language) throws Exception { + + ShoppingCart cart = shoppingCartService.getById(shoppingCartId); + + ReadableShoppingCart readableCart = null; + + if (cart != null) { + + readableCart = readableShoppingCartMapper.convert(cart, store, language); + + } + + return readableCart; + } + + @Override + public ShoppingCart getShoppingCartModel(Long id, MerchantStore store) throws Exception { + return shoppingCartService.getById(id); + } + + @Override + // KEEP + public ReadableShoppingCart getByCode(String code, MerchantStore store, Language language) throws Exception { + + ShoppingCart cart = shoppingCartService.getByCode(code, store); + ReadableShoppingCart readableCart = null; + + if (cart != null) { + + readableCart = readableShoppingCartMapper.convert(cart, store, language); + + if (!StringUtils.isBlank(cart.getPromoCode())) { + Date promoDateAdded = cart.getPromoAdded();// promo valid 1 day + if (promoDateAdded == null) { + promoDateAdded = new Date(); + } + Instant instant = promoDateAdded.toInstant(); + ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault()); + LocalDate date = zdt.toLocalDate(); + // date added < date + 1 day + LocalDate tomorrow = LocalDate.now().plusDays(1); + if (date.isBefore(tomorrow)) { + readableCart.setPromoCode(cart.getPromoCode()); + } + } + } + + return readableCart; + + } + + @Override + public void setOrderId(String code, Long orderId, MerchantStore store) throws Exception { + ShoppingCart cart = this.getShoppingCartModel(code, store); + if (cart == null) { + LOG.warn("Shopping cart with code [" + code + "] not found, expected to find a cart to set order id [" + + orderId + "]"); + } else { + cart.setOrderId(orderId); + } + saveOrUpdateShoppingCart(cart); + + } + + @Override + public ReadableShoppingCart modifyCart(String cartCode, String promo, MerchantStore store, Language language) + throws Exception { + + ShoppingCart cart = shoppingCartService.getByCode(cartCode, store); + + cart.setPromoCode(promo); + cart.setPromoAdded(new Date()); + + shoppingCartService.save(cart); + + return readableShoppingCartMapper.convert(cart, store, language); + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/store/facade/StoreFacade.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/store/facade/StoreFacade.java new file mode 100755 index 0000000000..f871df97cd --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/store/facade/StoreFacade.java @@ -0,0 +1,131 @@ +package com.salesmanager.shop.store.controller.store.facade; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import com.salesmanager.core.model.content.InputContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.merchant.MerchantStoreCriteria; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.store.PersistableBrand; +import com.salesmanager.shop.model.store.PersistableMerchantStore; +import com.salesmanager.shop.model.store.ReadableBrand; +import com.salesmanager.shop.model.store.ReadableMerchantStore; +import com.salesmanager.shop.model.store.ReadableMerchantStoreList; + +/** + * Layer between shop controllers, services and API with sm-core + * + * @author carlsamson + * + */ +public interface StoreFacade { + + /** + * Find MerchantStore model from store code + * + * @param code + * @return + * @throws Exception + */ + MerchantStore getByCode(HttpServletRequest request); + + MerchantStore get(String code); + + MerchantStore getByCode(String code); + + List supportedLanguages(MerchantStore store); + + ReadableMerchantStore getByCode(String code, String lang); + + ReadableMerchantStore getFullByCode(String code, String lang); + + ReadableMerchantStoreList findAll(MerchantStoreCriteria criteria, Language language, int page, int count); + + /** + * List child stores + * + * @param code + * @return + */ + ReadableMerchantStoreList getChildStores(Language language, String code, int start, int count); + + ReadableMerchantStore getByCode(String code, Language lang); + + ReadableMerchantStore getFullByCode(String code, Language language); + + boolean existByCode(String code); + + /** + * List MerchantStore using various criterias + * + * @param criteria + * @param lang + * @return + * @throws Exception + */ + ReadableMerchantStoreList getByCriteria(MerchantStoreCriteria criteria, Language lang); + + /** + * Creates a brand new MerchantStore + * + * @param store + * @throws Exception + */ + //ReadableMerchantStore create(PersistableMerchantStore store); + void create(PersistableMerchantStore store); + + /** + * Updates an existing store + * + * @param store + * @throws Exception + */ + //ReadableMerchantStore update(PersistableMerchantStore store); + void update(PersistableMerchantStore store); + + /** + * Deletes a MerchantStore based on store code + * + * @param code + */ + void delete(String code); + + /** + * Get Logo, social networks and other brand configurations + * + * @param code + * @return + */ + ReadableBrand getBrand(String code); + + /** + * Create store brand + * + * @param merchantStoreCode + * @param brand + */ + void createBrand(String merchantStoreCode, PersistableBrand brand); + + /** + * Delete store logo + */ + void deleteLogo(String code); + + /** + * Add MerchantStore logo + * + * @param code + * @param cmsContentImage + */ + void addStoreLogo(String code, InputContentFile cmsContentImage); + + /** + * Returns store id, code and name only + * + * @return + */ + List getMerchantStoreNames(MerchantStoreCriteria criteria); + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/store/facade/StoreFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/store/facade/StoreFacadeImpl.java new file mode 100755 index 0000000000..9834139d6a --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/store/facade/StoreFacadeImpl.java @@ -0,0 +1,584 @@ +package com.salesmanager.shop.store.controller.store.facade; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.Validate; +import org.drools.core.util.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.content.ContentService; +import com.salesmanager.core.business.services.merchant.MerchantStoreService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.services.system.MerchantConfigurationService; +import com.salesmanager.core.constants.MeasureUnit; +import com.salesmanager.core.model.common.GenericEntityList; +import com.salesmanager.core.model.content.InputContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.merchant.MerchantStoreCriteria; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.system.MerchantConfiguration; +import com.salesmanager.core.model.system.MerchantConfigurationType; +import com.salesmanager.shop.model.content.ReadableImage; +import com.salesmanager.shop.model.store.MerchantConfigEntity; +import com.salesmanager.shop.model.store.PersistableBrand; +import com.salesmanager.shop.model.store.PersistableMerchantStore; +import com.salesmanager.shop.model.store.ReadableBrand; +import com.salesmanager.shop.model.store.ReadableMerchantStore; +import com.salesmanager.shop.model.store.ReadableMerchantStoreList; +import com.salesmanager.shop.populator.store.PersistableMerchantStorePopulator; +import com.salesmanager.shop.populator.store.ReadableMerchantStorePopulator; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.utils.ImageFilePath; +import com.salesmanager.shop.utils.LanguageUtils; + +@Service("storeFacade") +public class StoreFacadeImpl implements StoreFacade { + + @Inject + private MerchantStoreService merchantStoreService; + + @Inject + private MerchantConfigurationService merchantConfigurationService; + + @Inject + private LanguageService languageService; + + @Inject + private ContentService contentService; + + @Inject + private PersistableMerchantStorePopulator persistableMerchantStorePopulator; + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + @Inject + private LanguageUtils languageUtils; + + @Autowired + private ReadableMerchantStorePopulator readableMerchantStorePopulator; + + private static final Logger LOG = LoggerFactory.getLogger(StoreFacadeImpl.class); + + @Override + public MerchantStore getByCode(HttpServletRequest request) { + String code = request.getParameter("store"); + if (StringUtils.isEmpty(code)) { + code = com.salesmanager.core.business.constants.Constants.DEFAULT_STORE; + } + return get(code); + } + + @Override + public MerchantStore get(String code) { + try { + MerchantStore store = merchantStoreService.getByCode(code); + return store; + } catch (ServiceException e) { + LOG.error("Error while getting MerchantStore", e); + throw new ServiceRuntimeException(e); + } + + } + + @Override + public ReadableMerchantStore getByCode(String code, String lang) { + Language language = getLanguage(lang); + return getByCode(code, language); + } + + @Override + public ReadableMerchantStore getFullByCode(String code, String lang) { + Language language = getLanguage(lang); + return getFullByCode(code, language); + } + + private Language getLanguage(String lang) { + return languageUtils.getServiceLanguage(lang); + } + + @Override + public ReadableMerchantStore getByCode(String code, Language language) { + MerchantStore store = getMerchantStoreByCode(code); + return convertMerchantStoreToReadableMerchantStore(language, store); + } + + @Override + public ReadableMerchantStore getFullByCode(String code, Language language) { + MerchantStore store = getMerchantStoreByCode(code); + return convertMerchantStoreToReadableMerchantStoreWithFullDetails(language, store); + } + + @Override + public boolean existByCode(String code) { + try { + return merchantStoreService.getByCode(code) != null; + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + } + + private ReadableMerchantStore convertMerchantStoreToReadableMerchantStore(Language language, MerchantStore store) { + ReadableMerchantStore readable = new ReadableMerchantStore(); + + /** + * Language is not important for this conversion using default language + */ + try { + readableMerchantStorePopulator.populate(store, readable, store, language); + } catch (Exception e) { + throw new ConversionRuntimeException("Error while populating MerchantStore " + e.getMessage()); + } + return readable; + } + + private ReadableMerchantStore convertMerchantStoreToReadableMerchantStoreWithFullDetails(Language language, MerchantStore store) { + ReadableMerchantStore readable = new ReadableMerchantStore(); + + + /** + * Language is not important for this conversion using default language + */ + try { + readableMerchantStorePopulator.populate(store, readable, store, language); + } catch (Exception e) { + throw new ConversionRuntimeException("Error while populating MerchantStore " + e.getMessage()); + } + return readable; + } + + private MerchantStore getMerchantStoreByCode(String code) { + return Optional.ofNullable(get(code)) + .orElseThrow(() -> new ResourceNotFoundException("Merchant store code [" + code + "] not found")); + } + + @Override + public void create(PersistableMerchantStore store) { + + Validate.notNull(store, "PersistableMerchantStore must not be null"); + Validate.notNull(store.getCode(), "PersistableMerchantStore.code must not be null"); + + // check if store code exists + MerchantStore storeForCheck = get(store.getCode()); + if (storeForCheck != null) { + throw new ServiceRuntimeException("MerhantStore " + store.getCode() + " already exists"); + } + + MerchantStore mStore = convertPersistableMerchantStoreToMerchantStore(store, languageService.defaultLanguage()); + createMerchantStore(mStore); + + } + + private void createMerchantStore(MerchantStore mStore) { + try { + merchantStoreService.saveOrUpdate(mStore); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + } + + private MerchantStore convertPersistableMerchantStoreToMerchantStore(PersistableMerchantStore store, + Language language) { + MerchantStore mStore = new MerchantStore(); + + // set default values + mStore.setWeightunitcode(MeasureUnit.KG.name()); + mStore.setSeizeunitcode(MeasureUnit.IN.name()); + + try { + mStore = persistableMerchantStorePopulator.populate(store, mStore, language); + } catch (ConversionException e) { + throw new ConversionRuntimeException(e); + } + return mStore; + } + + @Override + public void update(PersistableMerchantStore store) { + + Validate.notNull(store); + + MerchantStore mStore = mergePersistableMerchantStoreToMerchantStore(store, store.getCode(), + languageService.defaultLanguage()); + + updateMerchantStore(mStore); + + } + + private void updateMerchantStore(MerchantStore mStore) { + try { + merchantStoreService.update(mStore); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + + } + + private MerchantStore mergePersistableMerchantStoreToMerchantStore(PersistableMerchantStore store, String code, + Language language) { + + MerchantStore mStore = getMerchantStoreByCode(code); + + store.setId(mStore.getId()); + + try { + mStore = persistableMerchantStorePopulator.populate(store, mStore, language); + } catch (ConversionException e) { + throw new ConversionRuntimeException(e); + } + return mStore; + } + + @Override + public ReadableMerchantStoreList getByCriteria(MerchantStoreCriteria criteria, Language lang) { + return getMerchantStoresByCriteria(criteria, lang); + + } + + + + private ReadableMerchantStoreList getMerchantStoresByCriteria(MerchantStoreCriteria criteria, Language language) { + try { + GenericEntityList stores = Optional.ofNullable(merchantStoreService.getByCriteria(criteria)) + .orElseThrow(() -> new ResourceNotFoundException("Criteria did not match any store")); + + + ReadableMerchantStoreList storeList = new ReadableMerchantStoreList(); + storeList.setData( + (List) stores.getList().stream() + .map(s -> convertMerchantStoreToReadableMerchantStore(language, s)) + .collect(Collectors.toList()) + ); + storeList.setTotalPages(stores.getTotalPages()); + storeList.setRecordsTotal(stores.getTotalCount()); + storeList.setNumber(stores.getList().size()); + + return storeList; + + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + + } + + @Override + public void delete(String code) { + + if (MerchantStore.DEFAULT_STORE.equals(code.toUpperCase())) { + throw new ServiceRuntimeException("Cannot remove default store"); + } + + MerchantStore mStore = getMerchantStoreByCode(code); + + try { + merchantStoreService.delete(mStore); + } catch (Exception e) { + LOG.error("Error while deleting MerchantStore", e); + throw new ServiceRuntimeException("Error while deleting MerchantStore " + e.getMessage()); + } + + } + + @Override + public ReadableBrand getBrand(String code) { + MerchantStore mStore = getMerchantStoreByCode(code); + + ReadableBrand readableBrand = new ReadableBrand(); + if (!StringUtils.isEmpty(mStore.getStoreLogo())) { + String imagePath = imageUtils.buildStoreLogoFilePath(mStore); + ReadableImage image = createReadableImage(mStore.getStoreLogo(), imagePath); + readableBrand.setLogo(image); + } + List merchantConfigTOs = getMerchantConfigEntities(mStore); + readableBrand.getSocialNetworks().addAll(merchantConfigTOs); + return readableBrand; + } + + private List getMerchantConfigEntities(MerchantStore mStore) { + List configurations = getMergeConfigurationsByStore(MerchantConfigurationType.SOCIAL, + mStore); + + return configurations.stream().map(config -> convertToMerchantConfigEntity(config)) + .collect(Collectors.toList()); + } + + private List getMergeConfigurationsByStore(MerchantConfigurationType configurationType, + MerchantStore mStore) { + try { + return merchantConfigurationService.listByType(configurationType, mStore); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error wile getting merchantConfigurations " + e.getMessage()); + } + } + + private MerchantConfigEntity convertToMerchantConfigEntity(MerchantConfiguration config) { + MerchantConfigEntity configTO = new MerchantConfigEntity(); + configTO.setId(config.getId()); + configTO.setKey(config.getKey()); + configTO.setType(config.getMerchantConfigurationType()); + configTO.setValue(config.getValue()); + configTO.setActive(config.getActive() != null ? config.getActive().booleanValue() : false); + return configTO; + } + + private MerchantConfiguration convertToMerchantConfiguration(MerchantConfigEntity config, + MerchantConfigurationType configurationType) { + MerchantConfiguration configTO = new MerchantConfiguration(); + configTO.setId(config.getId()); + configTO.setKey(config.getKey()); + configTO.setMerchantConfigurationType(configurationType); + configTO.setValue(config.getValue()); + configTO.setActive(new Boolean(config.isActive())); + return configTO; + } + + private ReadableImage createReadableImage(String storeLogo, String imagePath) { + ReadableImage image = new ReadableImage(); + image.setName(storeLogo); + image.setPath(imagePath); + return image; + } + + @Override + public void deleteLogo(String code) { + MerchantStore store = getByCode(code); + String image = store.getStoreLogo(); + store.setStoreLogo(null); + + try { + updateMerchantStore(store); + if (!StringUtils.isEmpty(image)) { + contentService.removeFile(store.getCode(), image); + } + } catch (ServiceException e) { + throw new ServiceRuntimeException(e.getMessage()); + } + } + + @Override + public MerchantStore getByCode(String code) { + return getMerchantStoreByCode(code); + } + + @Override + public void addStoreLogo(String code, InputContentFile cmsContentImage) { + MerchantStore store = getByCode(code); + store.setStoreLogo(cmsContentImage.getFileName()); + saveMerchantStore(store); + addLogoToStore(code, cmsContentImage); + } + + private void addLogoToStore(String code, InputContentFile cmsContentImage) { + try { + contentService.addLogo(code, cmsContentImage); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + } + + private void saveMerchantStore(MerchantStore store) { + try { + merchantStoreService.save(store); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + + } + + @Override + public void createBrand(String merchantStoreCode, PersistableBrand brand) { + MerchantStore mStore = getMerchantStoreByCode(merchantStoreCode); + + List createdConfigs = brand.getSocialNetworks(); + + List configurations = createdConfigs.stream() + .map(config -> convertToMerchantConfiguration(config, MerchantConfigurationType.SOCIAL)) + .collect(Collectors.toList()); + try { + for (MerchantConfiguration mConfigs : configurations) { + mConfigs.setMerchantStore(mStore); + if (!StringUtils.isEmpty(mConfigs.getValue())) { + mConfigs.setMerchantConfigurationType(MerchantConfigurationType.SOCIAL); + merchantConfigurationService.saveOrUpdate(mConfigs); + } else {// remove if submited blank and exists + MerchantConfiguration config = merchantConfigurationService + .getMerchantConfiguration(mConfigs.getKey(), mStore); + if (config != null) { + merchantConfigurationService.delete(config); + } + } + } + } catch (ServiceException se) { + throw new ServiceRuntimeException(se); + } + + } + + @Override + public ReadableMerchantStoreList getChildStores(Language language, String code, int page, int count) { + try { + + // first check if store is retailer + MerchantStore retailer = this.getByCode(code); + if (retailer == null) { + throw new ResourceNotFoundException("Merchant [" + code + "] not found"); + } + + if (retailer.isRetailer() == null || !retailer.isRetailer().booleanValue()) { + throw new ResourceNotFoundException("Merchant [" + code + "] not a retailer"); + } + + + Page children = merchantStoreService.listChildren(code, page, count); + List readableStores = new ArrayList(); + ReadableMerchantStoreList readableList = new ReadableMerchantStoreList(); + if (!CollectionUtils.isEmpty(children.getContent())) { + for (MerchantStore store : children) + readableStores.add(convertMerchantStoreToReadableMerchantStore(language, store)); + } + readableList.setData(readableStores); + readableList.setRecordsFiltered(children.getSize()); + readableList.setTotalPages(children.getTotalPages()); + readableList.setRecordsTotal(children.getTotalElements()); + readableList.setNumber(children.getNumber()); + + return readableList; + + + +/* List children = merchantStoreService.listChildren(code); + List readableStores = new ArrayList(); + if (!CollectionUtils.isEmpty(children)) { + for (MerchantStore store : children) + readableStores.add(convertMerchantStoreToReadableMerchantStore(language, store)); + } + return readableStores;*/ + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + + } + + @Override + public ReadableMerchantStoreList findAll(MerchantStoreCriteria criteria, Language language, int page, int count) { + + try { + Page stores = null; + List readableStores = new ArrayList(); + ReadableMerchantStoreList readableList = new ReadableMerchantStoreList(); + + Optional code = Optional.ofNullable(criteria.getStoreCode()); + Optional name = Optional.ofNullable(criteria.getName()); + if(code.isPresent()) { + + stores = merchantStoreService.listByGroup(name, code.get(), page, count); + + } else { + if(criteria.isRetailers()) { + stores = merchantStoreService.listAllRetailers(name, page, count); + } else { + stores = merchantStoreService.listAll(name, page, count); + } + } + + + if (!CollectionUtils.isEmpty(stores.getContent())) { + for (MerchantStore store : stores) + readableStores.add(convertMerchantStoreToReadableMerchantStore(language, store)); + } + readableList.setData(readableStores); + readableList.setRecordsTotal(stores.getTotalElements()); + readableList.setTotalPages(stores.getTotalPages()); + readableList.setNumber(stores.getSize()); + readableList.setRecordsFiltered(stores.getSize()); + return readableList; + + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while finding all merchant", e); + } + + + } + + private ReadableMerchantStore convertStoreName(MerchantStore store) { + ReadableMerchantStore convert = new ReadableMerchantStore(); + convert.setId(store.getId()); + convert.setCode(store.getCode()); + convert.setName(store.getStorename()); + return convert; + } + + @Override + public List getMerchantStoreNames(MerchantStoreCriteria criteria) { + Validate.notNull(criteria, "MerchantStoreCriteria must not be null"); + + try { + + List stores = null; + Optional code = Optional.ofNullable(criteria.getStoreCode()); + + + //TODO Pageable + if(code.isPresent()) { + + stores = merchantStoreService.findAllStoreNames(code.get()).stream() + .map(s -> convertStoreName(s)) + .collect(Collectors.toList()); + } else { + stores = merchantStoreService.findAllStoreNames().stream() + .map(s -> convertStoreName(s)) + .collect(Collectors.toList()); + } + + + return stores; + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while getting store name",e); + } + + + } + + @Override + public List supportedLanguages(MerchantStore store) { + + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(store.getClass(), "MerchantStore code cannot be null"); + + if(!CollectionUtils.isEmpty(store.getLanguages())) { + return store.getLanguages(); + } + + //refresh + try { + store = merchantStoreService.getByCode(store.getCode()); + } catch (ServiceException e) { + throw new ServiceRuntimeException("An exception occured when getting store [" + store.getCode() + "]"); + } + + if(store!=null) { + return store.getLanguages(); + } + + return Collections.emptyList(); + } + +} \ No newline at end of file diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/system/MerchantConfigurationFacade.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/system/MerchantConfigurationFacade.java new file mode 100755 index 0000000000..cf96eb64f4 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/system/MerchantConfigurationFacade.java @@ -0,0 +1,11 @@ +package com.salesmanager.shop.store.controller.system; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.system.Configs; + +public interface MerchantConfigurationFacade { + + Configs getMerchantConfig(MerchantStore merchantStore, Language language); + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/system/MerchantConfigurationFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/system/MerchantConfigurationFacadeImpl.java new file mode 100755 index 0000000000..4831b444d5 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/system/MerchantConfigurationFacadeImpl.java @@ -0,0 +1,101 @@ +package com.salesmanager.shop.store.controller.system; + +import static com.salesmanager.shop.constants.Constants.KEY_FACEBOOK_PAGE_URL; +import static com.salesmanager.shop.constants.Constants.KEY_GOOGLE_ANALYTICS_URL; +import static com.salesmanager.shop.constants.Constants.KEY_INSTAGRAM_URL; +import static com.salesmanager.shop.constants.Constants.KEY_PINTEREST_PAGE_URL; + +import java.util.Optional; + +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.system.MerchantConfigurationService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.system.MerchantConfig; +import com.salesmanager.core.model.system.MerchantConfiguration; +import com.salesmanager.shop.model.system.Configs; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; + + +@Service +public class MerchantConfigurationFacadeImpl implements MerchantConfigurationFacade { + + private static final Logger LOGGER = LoggerFactory + .getLogger(MerchantConfigurationFacadeImpl.class); + + @Inject + private MerchantConfigurationService merchantConfigurationService; + + @Value("${config.displayShipping}") + private String displayShipping; + + @Override + public Configs getMerchantConfig(MerchantStore merchantStore, Language language) { + + MerchantConfig configs = getMerchantConfig(merchantStore); + + Configs readableConfig = new Configs(); + readableConfig.setAllowOnlinePurchase(configs.isAllowPurchaseItems()); + readableConfig.setDisplaySearchBox(configs.isDisplaySearchBox()); + readableConfig.setDisplayContactUs(configs.isDisplayContactUs()); + + readableConfig.setDisplayCustomerSection(configs.isDisplayCustomerSection()); + readableConfig.setDisplayAddToCartOnFeaturedItems(configs.isDisplayAddToCartOnFeaturedItems()); + readableConfig.setDisplayCustomerAgreement(configs.isDisplayCustomerAgreement()); + readableConfig.setDisplayPagesMenu(configs.isDisplayPagesMenu()); + + Optional facebookConfigValue = getConfigValue(KEY_FACEBOOK_PAGE_URL, merchantStore); + facebookConfigValue.ifPresent(readableConfig::setFacebook); + + Optional googleConfigValue = getConfigValue(KEY_GOOGLE_ANALYTICS_URL, merchantStore); + googleConfigValue.ifPresent(readableConfig::setGa); + + Optional instagramConfigValue = getConfigValue(KEY_INSTAGRAM_URL, merchantStore); + instagramConfigValue.ifPresent(readableConfig::setInstagram); + + + Optional pinterestConfigValue = getConfigValue(KEY_PINTEREST_PAGE_URL, merchantStore); + pinterestConfigValue.ifPresent(readableConfig::setPinterest); + + readableConfig.setDisplayShipping(false); + try { + if(!StringUtils.isBlank(displayShipping)) { + readableConfig.setDisplayShipping(Boolean.valueOf(displayShipping)); + } + } catch(Exception e) { + LOGGER.error("Cannot parse value of " + displayShipping); + } + + return readableConfig; + } + + private MerchantConfig getMerchantConfig(MerchantStore merchantStore) { + try{ + return merchantConfigurationService.getMerchantConfig(merchantStore); + } catch (ServiceException e){ + throw new ServiceRuntimeException(e); + } + } + + private Optional getConfigValue(String keyContant, MerchantStore merchantStore) { + return getMerchantConfiguration(keyContant, merchantStore) + .map(MerchantConfiguration::getValue); + } + + private Optional getMerchantConfiguration(String key, MerchantStore merchantStore) { + try{ + return Optional.ofNullable(merchantConfigurationService.getMerchantConfiguration(key, merchantStore)); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/zone/facade/ZoneFacade.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/zone/facade/ZoneFacade.java new file mode 100755 index 0000000000..8ad1cdae29 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/zone/facade/ZoneFacade.java @@ -0,0 +1,13 @@ +package com.salesmanager.shop.store.controller.zone.facade; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.shop.model.references.ReadableZone; +import java.util.List; + +public interface ZoneFacade { + + List getZones(String countryCode, Language language, MerchantStore merchantStore); + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/controller/zone/facade/ZoneFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/zone/facade/ZoneFacadeImpl.java new file mode 100755 index 0000000000..15adfb9d9b --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/controller/zone/facade/ZoneFacadeImpl.java @@ -0,0 +1,56 @@ +package com.salesmanager.shop.store.controller.zone.facade; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.reference.zone.ZoneService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.shop.model.references.ReadableZone; +import com.salesmanager.shop.populator.references.ReadableZonePopulator; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; + +@Service +public class ZoneFacadeImpl implements ZoneFacade { + + @Inject + private ZoneService zoneService; + + @Override + public List getZones(String countryCode, Language language, MerchantStore merchantStore) { + List listZones = getListZones(countryCode, language); + if (listZones.isEmpty()){ + return Collections.emptyList(); + //throw new ResourceNotFoundException("No zones found"); + } + return listZones.stream() + .map(zone -> convertToReadableZone(zone, language, merchantStore)) + .collect(Collectors.toList()); + } + + private ReadableZone convertToReadableZone(Zone zone, Language language, MerchantStore merchantStore) { + try{ + ReadableZonePopulator populator = new ReadableZonePopulator(); + return populator.populate(zone, new ReadableZone(), merchantStore, language); + } catch (ConversionException e){ + throw new ConversionRuntimeException(e); + } + } + + private List getListZones(String countryCode, Language language) { + try{ + return zoneService.getZones(countryCode, language); + } catch (ServiceException e){ + throw new ServiceRuntimeException(e); + } + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/catalog/CatalogFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/catalog/CatalogFacadeImpl.java new file mode 100644 index 0000000000..013bae3566 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/catalog/CatalogFacadeImpl.java @@ -0,0 +1,240 @@ +package com.salesmanager.shop.store.facade.catalog; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.catalog.CatalogEntryService; +import com.salesmanager.core.business.services.catalog.catalog.CatalogService; +import com.salesmanager.core.model.catalog.catalog.Catalog; +import com.salesmanager.core.model.catalog.catalog.CatalogCategoryEntry; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.mapper.catalog.PersistableCatalogMapper; +import com.salesmanager.shop.mapper.catalog.ReadableCatalogCategoryEntryMapper; +import com.salesmanager.shop.mapper.catalog.ReadableCatalogMapper; +import com.salesmanager.shop.model.catalog.catalog.PersistableCatalog; +import com.salesmanager.shop.model.catalog.catalog.PersistableCatalogCategoryEntry; +import com.salesmanager.shop.model.catalog.catalog.ReadableCatalog; +import com.salesmanager.shop.model.catalog.catalog.ReadableCatalogCategoryEntry; +import com.salesmanager.shop.model.entity.ReadableEntityList; +import com.salesmanager.shop.store.api.exception.OperationNotAllowedException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.catalog.facade.CatalogFacade; +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +import static com.salesmanager.shop.util.ReadableEntityUtil.createReadableList; + +@Service("catalogFacade") +public class CatalogFacadeImpl implements CatalogFacade { + + + @Autowired + private CatalogService catalogService; + + @Autowired + private CatalogEntryService catalogEntryService; + + @Autowired + private PersistableCatalogMapper persistableCatalogMapper; + + @Autowired + private ReadableCatalogMapper readableCatalogMapper; + + @Autowired + private Mapper persistableCatalogEntryMapper; + + @Autowired + private ReadableCatalogCategoryEntryMapper readableCatalogEntryMapper; + + + @Override + public ReadableCatalog saveCatalog(PersistableCatalog catalog, MerchantStore store, Language language) { + Validate.notNull(catalog, "Catalog cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + Catalog catalogToSave = persistableCatalogMapper.convert(catalog, store, language); + + boolean existByCode = uniqueCatalog(catalog.getCode(), store); + if (existByCode) { + throw new OperationNotAllowedException("Catalog [" + catalog.getCode() + "] already exists"); + } + catalogService.saveOrUpdate(catalogToSave, store); + Catalog savedCatalog = catalogService.getByCode(catalogToSave.getCode(), store).get(); + return readableCatalogMapper.convert(savedCatalog, store, language); + } + + @Override + public void deleteCatalog(Long catalogId, MerchantStore store, Language language) { + Validate.notNull(catalogId, "Catalog id cannot be null"); + Validate.isTrue(catalogId > 0, "Catalog id cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + + Catalog c = catalogService.getById(catalogId); + + if (Objects.isNull(c)) { + throw new ResourceNotFoundException("Catalog with id [" + catalogId + "] not found"); + } + + if (Objects.nonNull(c.getMerchantStore()) && !c.getMerchantStore().getCode().equals(store.getCode())) { + throw new ResourceNotFoundException("Catalog with id [" + catalogId + "] not found for merchant [" + store.getCode() + "]"); + } + + try { + catalogService.delete(c); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while deleting catalog id [" + catalogId + "]", e); + } + + } + + @Override + public ReadableCatalog getCatalog(String code, MerchantStore store, Language language) { + Validate.notNull(code, "Catalog code cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + + Catalog catalog = catalogService.getByCode(code, store) + .orElseThrow(() -> new ResourceNotFoundException("Catalog with code [" + code + "] not found")); + return readableCatalogMapper.convert(catalog, store, language); + } + + @Override + public void updateCatalog(Long catalogId, PersistableCatalog catalog, MerchantStore store, Language language) { + Validate.notNull(catalogId, "Catalog id cannot be null"); + Validate.isTrue(catalogId > 0, "Catalog id cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + + Catalog c = Optional.ofNullable(catalogService.getById(catalogId)) + .orElseThrow(() -> new ResourceNotFoundException("Catalog with id [" + catalogId + "] not found")); + + if (Objects.nonNull(c.getMerchantStore()) && !c.getMerchantStore().getCode().equals(store.getCode())) { + throw new ResourceNotFoundException("Catalog with id [" + catalogId + "] not found for merchant [" + store.getCode() + "]"); + } + + c.setDefaultCatalog(catalog.isDefaultCatalog()); + c.setVisible(catalog.isVisible()); + + catalogService.saveOrUpdate(c, store); + } + + @Override + public ReadableCatalog getCatalog(Long id, MerchantStore store, Language language) { + Validate.notNull(id, "Catalog id cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + + Catalog catalog = catalogService.getById(id, store) + .orElseThrow(() -> new ResourceNotFoundException("Catalog with id [" + id + "] not found")); + return readableCatalogMapper.convert(catalog, store, language); + } + + @Override + public Catalog getCatalog(String code, MerchantStore store) { + Validate.notNull(code, "Catalog code cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + + return catalogService.getByCode(code, store).get(); + } + + @Override + public ReadableEntityList getListCatalogs(Optional code, MerchantStore store, Language language, int page, int count) { + Validate.notNull(store, "MerchantStore cannot be null"); + + String catalogCode = code.orElse(null); + Page catalogs = catalogService.getCatalogs(store, language, catalogCode, page, count); + if (catalogs.isEmpty()) { + return new ReadableEntityList<>(); + } + + List readableList = catalogs.getContent().stream() + .map(cat -> readableCatalogMapper.convert(cat, store, language)) + .collect(Collectors.toList()); + return createReadableList(catalogs, readableList); + } + + @Override + public ReadableEntityList listCatalogEntry(Optional product, Long id, MerchantStore store, Language language, int page, int count) { + Validate.notNull(store, "MerchantStore cannot be null"); + + String productCode = product.orElse(null); + Catalog catalog = catalogService.getById(id, store) + .orElseThrow(() -> new ResourceNotFoundException("Catalog with id [" + id + "] not found for store [" + store.getCode() + "]")); + + Page entries = catalogEntryService.list(catalog, store, language, productCode, page, count); + + if (entries.isEmpty()) { + return new ReadableEntityList<>(); + } + + List readableList = entries.getContent().stream() + .map(cat -> readableCatalogEntryMapper.convert(cat, store, language)) + .collect(Collectors.toList()); + return createReadableList(entries, readableList); + } + + @Override + public ReadableCatalogCategoryEntry getCatalogEntry(Long id, MerchantStore store, Language language) { + CatalogCategoryEntry entry = catalogEntryService.getById(id); + if (Objects.isNull(entry)) { + throw new ResourceNotFoundException("catalog entry [" + id + "] not found"); + } + + if (entry.getCatalog().getMerchantStore().getId().intValue() != store.getId().intValue()) { + throw new ResourceNotFoundException("catalog entry [" + id + "] not found"); + } + return readableCatalogEntryMapper.convert(entry, store, language); + } + + @Override + public ReadableCatalogCategoryEntry addCatalogEntry(PersistableCatalogCategoryEntry entry, MerchantStore store, Language language) { + + Validate.notNull(entry, "PersistableCatalogEntry cannot be null"); + Validate.notNull(entry.getCatalog(), "CatalogEntry.catalog cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + + Catalog catalog = catalogService.getByCode(entry.getCatalog(), store) + .orElseThrow(() -> new ResourceNotFoundException("catalog [" + entry.getCatalog() + "] not found")); + + CatalogCategoryEntry catalogEntryModel = persistableCatalogEntryMapper.convert(entry, store, language); + catalogEntryService.add(catalogEntryModel, catalog); + return readableCatalogEntryMapper.convert(catalogEntryModel, store, language); + + } + + @Override + public void removeCatalogEntry(Long catalogId, Long catalogEntryId, MerchantStore store, Language language) { + CatalogCategoryEntry entry = catalogEntryService.getById(catalogEntryId); + if (Objects.isNull(entry)) { + throw new ResourceNotFoundException("catalog entry [" + catalogEntryId + "] not found"); + } + + if (entry.getCatalog().getId().longValue() != catalogId.longValue()) { + throw new ResourceNotFoundException("catalog entry [" + catalogEntryId + "] not found"); + } + + if (entry.getCatalog().getMerchantStore().getId().intValue() != store.getId().intValue()) { + throw new ResourceNotFoundException("catalog entry [" + catalogEntryId + "] not found"); + } + + try { + catalogEntryService.delete(entry); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while deleting catalogEntry", e); + } + + } + + @Override + public boolean uniqueCatalog(String code, MerchantStore store) { + return catalogService.existByCode(code, store); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/category/CategoryFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/category/CategoryFacadeImpl.java new file mode 100755 index 0000000000..1a992328ad --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/category/CategoryFacadeImpl.java @@ -0,0 +1,558 @@ +package com.salesmanager.shop.store.facade.category; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import org.apache.commons.lang3.Validate; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.category.CategoryService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService; +import com.salesmanager.core.business.services.merchant.MerchantStoreService; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValueDescription; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.category.PersistableCategory; +import com.salesmanager.shop.model.catalog.category.ReadableCategory; +import com.salesmanager.shop.model.catalog.category.ReadableCategoryList; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductVariant; +import com.salesmanager.shop.model.catalog.product.attribute.ReadableProductVariantValue; +import com.salesmanager.shop.model.entity.ListCriteria; +import com.salesmanager.shop.populator.catalog.PersistableCategoryPopulator; +import com.salesmanager.shop.populator.catalog.ReadableCategoryPopulator; +import com.salesmanager.shop.store.api.exception.OperationNotAllowedException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.api.exception.UnauthorizedException; +import com.salesmanager.shop.store.controller.category.facade.CategoryFacade; + +@Service(value = "categoryFacade") +public class CategoryFacadeImpl implements CategoryFacade { + + @Inject + private CategoryService categoryService; + + @Inject + private MerchantStoreService merchantStoreService; + + @Inject + private PersistableCategoryPopulator persistableCatagoryPopulator; + + @Inject + private Mapper categoryReadableCategoryConverter; + + @Inject + private ProductAttributeService productAttributeService; + + private static final String FEATURED_CATEGORY = "featured"; + private static final String VISIBLE_CATEGORY = "visible"; + private static final String ADMIN_CATEGORY = "admin"; + + @Override + public ReadableCategoryList getCategoryHierarchy(MerchantStore store, ListCriteria criteria, int depth, + Language language, List filter, int page, int count) { + + Validate.notNull(store,"MerchantStore can not be null"); + + + //get parent store + try { + + MerchantStore parent = merchantStoreService.getParent(store.getCode()); + + + List categories = null; + ReadableCategoryList returnList = new ReadableCategoryList(); + if (!CollectionUtils.isEmpty(filter) && filter.contains(FEATURED_CATEGORY)) { + categories = categoryService.getListByDepthFilterByFeatured(parent, depth, language); + returnList.setRecordsTotal(categories.size()); + returnList.setNumber(categories.size()); + returnList.setTotalPages(1); + } else { + org.springframework.data.domain.Page pageable = categoryService.getListByDepth(parent, language, + criteria != null ? criteria.getName() : null, depth, page, count); + categories = pageable.getContent(); + returnList.setRecordsTotal(pageable.getTotalElements()); + returnList.setTotalPages(pageable.getTotalPages()); + returnList.setNumber(categories.size()); + } + + + + List readableCategories = null; + if (filter != null && filter.contains(VISIBLE_CATEGORY)) { + readableCategories = categories.stream().filter(Category::isVisible) + .map(cat -> categoryReadableCategoryConverter.convert(cat, store, language)) + .collect(Collectors.toList()); + } else { + readableCategories = categories.stream() + .map(cat -> categoryReadableCategoryConverter.convert(cat, store, language)) + .collect(Collectors.toList()); + } + + Map readableCategoryMap = readableCategories.stream() + .collect(Collectors.toMap(ReadableCategory::getId, Function.identity())); + + readableCategories.stream() + // .filter(ReadableCategory::isVisible) + .filter(cat -> Objects.nonNull(cat.getParent())) + .filter(cat -> readableCategoryMap.containsKey(cat.getParent().getId())).forEach(readableCategory -> { + ReadableCategory parentCategory = readableCategoryMap.get(readableCategory.getParent().getId()); + if (parentCategory != null) { + parentCategory.getChildren().add(readableCategory); + } + }); + + List filteredList = readableCategoryMap.values().stream().collect(Collectors.toList()); + + //execute only if not admin filtered + if(filter == null || (filter!=null && !filter.contains(ADMIN_CATEGORY))) { + filteredList = readableCategoryMap.values().stream().filter(cat -> cat.getDepth() == 0) + .sorted(Comparator.comparing(ReadableCategory::getSortOrder)).collect(Collectors.toList()); + + returnList.setNumber(filteredList.size()); + + } + + returnList.setCategories(filteredList); + + + + return returnList; + + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + + } + + @Override + public boolean existByCode(MerchantStore store, String code) { + try { + Category c = categoryService.getByCode(store, code); + return c != null ? true : false; + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + } + + @Override + public PersistableCategory saveCategory(MerchantStore store, PersistableCategory category) { + try { + + Long categoryId = category.getId(); + Category target = Optional.ofNullable(categoryId) + .filter(merchant -> store !=null) + .filter(id -> id > 0) + .map(categoryService::getById) + .orElse(new Category()); + + Category dbCategory = populateCategory(store, category, target); + saveCategory(store, dbCategory, null); + + // set category id + category.setId(dbCategory.getId()); + return category; + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while updating category", e); + } + } + + private Category populateCategory(MerchantStore store, PersistableCategory category, Category target) { + try { + return persistableCatagoryPopulator.populate(category, target, store, store.getDefaultLanguage()); + } catch (ConversionException e) { + throw new ServiceRuntimeException(e); + } + } + + private void saveCategory(MerchantStore store, Category category, Category parent) throws ServiceException { + + /** + * c.children1 + * + *

    + * children1.children1 children1.children2 + * + *

    + * children1.children2.children1 + */ + + /** set lineage * */ + if (parent != null) { + category.setParent(category); + + String lineage = parent.getLineage(); + int depth = parent.getDepth(); + + category.setDepth(depth + 1); + category.setLineage(new StringBuilder().append(lineage).toString());// service + // will + // adjust + // lineage + } + + category.setMerchantStore(store); + + // remove children + List children = category.getCategories(); + List saveAfter = children.stream().filter(c -> c.getId() == null || c.getId().longValue()==0).collect(Collectors.toList()); + List saveNow = children.stream().filter(c -> c.getId() != null && c.getId().longValue()>0).collect(Collectors.toList()); + category.setCategories(saveNow); + + /** set parent * */ + if (parent != null) { + category.setParent(parent); + } + + categoryService.saveOrUpdate(category); + + if (!CollectionUtils.isEmpty(saveAfter)) { + parent = category; + for(Category c: saveAfter) { + if(c.getId() == null || c.getId().longValue()==0) { + for (Category sub : children) { + saveCategory(store, sub, parent); + } + } + } + } + + } + + @Override + public ReadableCategory getById(MerchantStore store, Long id, Language language) { + + Category categoryModel = null; + if (language != null) { + categoryModel = getCategoryById(id, language); + } else {// all langs + categoryModel = getById(store, id); + } + + if (categoryModel == null) + throw new ResourceNotFoundException("Categori id [" + id + "] not found"); + + StringBuilder lineage = new StringBuilder().append(categoryModel.getLineage()); + + ReadableCategory readableCategory = categoryReadableCategoryConverter.convert(categoryModel, store, + language); + + // get children + List children = getListByLineage(store, lineage.toString()); + + List childrenCats = children.stream() + .map(cat -> categoryReadableCategoryConverter.convert(cat, store, language)) + .collect(Collectors.toList()); + + addChildToParent(readableCategory, childrenCats); + return readableCategory; + + } + + private void addChildToParent(ReadableCategory readableCategory, List childrenCats) { + Map categoryMap = childrenCats.stream() + .collect(Collectors.toMap(ReadableCategory::getId, Function.identity())); + categoryMap.put(readableCategory.getId(), readableCategory); + + // traverse map and add child to parent + for (ReadableCategory readable : childrenCats) { + + if (readable.getParent() != null) { + + ReadableCategory rc = categoryMap.get(readable.getParent().getId()); + if (rc != null) { + rc.getChildren().add(readable); + } + } + } + } + + private List getListByLineage(MerchantStore store, String lineage) { + try { + return categoryService.getListByLineage(store, lineage); + } catch (ServiceException e) { + throw new ServiceRuntimeException(String.format("Error while getting root category %s", e.getMessage()), e); + } + } + + private Category getCategoryById(Long id, Language language) { + return Optional.ofNullable(categoryService.getOneByLanguage(id, language)) + .orElseThrow(() -> new ResourceNotFoundException("Category id [" + id + "] not found")); + } + + @Override + public void deleteCategory(Category category) { + try { + categoryService.delete(category); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while deleting category", e); + } + } + + @Override + public ReadableCategory getByCode(MerchantStore store, String code, Language language) throws Exception { + + Validate.notNull(code, "category code must not be null"); + ReadableCategoryPopulator categoryPopulator = new ReadableCategoryPopulator(); + ReadableCategory readableCategory = new ReadableCategory(); + + Category category = categoryService.getByCode(store, code); + categoryPopulator.populate(category, readableCategory, store, language); + + return readableCategory; + } + + @Override + public ReadableCategory getCategoryByFriendlyUrl(MerchantStore store, String friendlyUrl, Language language) throws Exception { + Validate.notNull(friendlyUrl, "Category search friendly URL must not be null"); + ReadableCategoryPopulator categoryPopulator = new ReadableCategoryPopulator(); + ReadableCategory readableCategory = new ReadableCategory(); + + Category category = categoryService.getBySeUrl(store, friendlyUrl); + categoryPopulator.populate(category, readableCategory, store, language); + + return readableCategory; + } + + private Category getById(MerchantStore store, Long id) { + Validate.notNull(id, "category id must not be null"); + Validate.notNull(store, "MerchantStore must not be null"); + Category category = categoryService.getById(id, store.getId()); + if (category == null) { + throw new ResourceNotFoundException("Category with id [" + id + "] not found"); + } + if (category.getMerchantStore().getId().intValue() != store.getId().intValue()) { + throw new UnauthorizedException("Unauthorized"); + } + return category; + } + + @Override + public void deleteCategory(Long categoryId, MerchantStore store) { + Category category = getOne(categoryId, store.getId()); + deleteCategory(category); + } + + private Category getOne(Long categoryId, int storeId) { + return Optional.ofNullable(categoryService.getById(categoryId)).orElseThrow( + () -> new ResourceNotFoundException(String.format("No Category found for ID : %s", categoryId))); + } + + @Override + public List categoryProductVariants(Long categoryId, MerchantStore store, + Language language) { + Category category = categoryService.getById(categoryId, store.getId()); + + List variants = new ArrayList(); + + if (category == null) { + throw new ResourceNotFoundException("Category [" + categoryId + "] not found"); + } + + try { + List attributes = productAttributeService.getProductAttributesByCategoryLineage(store, + category.getLineage(), language); + + /** + * Option NAME OptionValueName OptionValueName + **/ + Map> rawFacet = new HashMap>(); + Map references = new HashMap(); + for (ProductAttribute attr : attributes) { + references.put(attr.getProductOption().getCode(), attr.getProductOption()); + List values = rawFacet.get(attr.getProductOption().getCode()); + if (values == null) { + values = new ArrayList(); + rawFacet.put(attr.getProductOption().getCode(), values); + } + + if(attr.getProductOptionValue() != null) { + Optional desc = attr.getProductOptionValue().getDescriptions() + .stream().filter(o -> o.getLanguage().getId() == language.getId()).findFirst(); + + com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValue val = new com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValue(); + val.setCode(attr.getProductOption().getCode()); + String order = attr.getAttributeSortOrder(); + val.setSortOrder(order == null ? attr.getId().intValue(): Integer.parseInt(attr.getAttributeSortOrder())); + if(desc.isPresent()) { + val.setName(desc.get().getName()); + } else { + val.setName(attr.getProductOption().getCode()); + } + values.add(val); + } + } + + // for each reference set Option + Iterator> it = references.entrySet().iterator(); + while (it.hasNext()) { + @SuppressWarnings("rawtypes") + Map.Entry pair = (Map.Entry) it.next(); + ProductOption option = (ProductOption) pair.getValue(); + List values = rawFacet.get(option.getCode()); + + ReadableProductVariant productVariant = new ReadableProductVariant(); + Optional optionDescription = option.getDescriptions().stream().filter(o -> o.getLanguage().getId() == language.getId()).findFirst(); + if(optionDescription.isPresent()) { + productVariant.setName(optionDescription.get().getName()); + productVariant.setId(optionDescription.get().getId()); + productVariant.setCode(optionDescription.get().getProductOption().getCode()); + List optionValues = new ArrayList(); + for (com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValue value : values) { + ReadableProductVariantValue v = new ReadableProductVariantValue(); + v.setCode(value.getCode()); + v.setName(value.getName()); + v.setDescription(value.getName()); + v.setOption(option.getId()); + v.setValue(value.getId()); + v.setOrder(option.getProductOptionSortOrder()); + optionValues.add(v); + } + + Comparator orderComparator + = Comparator.comparingInt(ReadableProductVariantValue::getOrder); + + //Arrays.sort(employees, employeeSalaryComparator); + + List readableValues = optionValues.stream() + .sorted(orderComparator) + .collect(Collectors.toList()); + + + + //sort by name + // remove duplicates + readableValues = optionValues.stream().distinct().collect(Collectors.toList()); + readableValues.sort(Comparator.comparing(ReadableProductVariantValue::getName)); + + productVariant.setOptions(readableValues); + variants.add(productVariant); + } + } + + + return variants; + } catch (Exception e) { + throw new ServiceRuntimeException("An error occured while retrieving ProductAttributes", e); + } + } + + @Override + public void move(Long child, Long parent, MerchantStore store) { + + Validate.notNull(child, "Child category must not be null"); + Validate.notNull(parent, "Parent category must not be null"); + Validate.notNull(store, "Merhant must not be null"); + + + try { + + Category c = categoryService.getById(child, store.getId()); + + if(c == null) { + throw new ResourceNotFoundException("Category with id [" + child + "] for store [" + store.getCode() + "]"); + } + + if(parent.longValue()==-1) { + categoryService.addChild(null, c); + return; + + } + + Category p = categoryService.getById(parent, store.getId()); + + if(p == null) { + throw new ResourceNotFoundException("Category with id [" + parent + "] for store [" + store.getCode() + "]"); + } + + if (c.getParent() != null && c.getParent().getId() == parent) { + return; + } + + if (c.getMerchantStore().getId().intValue() != store.getId().intValue()) { + throw new OperationNotAllowedException( + "Invalid identifiers for Merchant [" + c.getMerchantStore().getCode() + "]"); + } + + if (p.getMerchantStore().getId().intValue() != store.getId().intValue()) { + throw new OperationNotAllowedException( + "Invalid identifiers for Merchant [" + c.getMerchantStore().getCode() + "]"); + } + + p.getAuditSection().setModifiedBy("Api"); + categoryService.addChild(p, c); + } catch (ResourceNotFoundException re) { + throw re; + } catch (OperationNotAllowedException oe) { + throw oe; + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + + } + + @Override + public Category getByCode(String code, MerchantStore store) { + try { + return categoryService.getByCode(store, code); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while reading category code [" + code + "]",e); + } + } + + @Override + public void setVisible(PersistableCategory category, MerchantStore store) { + Validate.notNull(category, "Category must not be null"); + Validate.notNull(store, "Store must not be null"); + try { + Category c = this.getById(store, category.getId()); + c.setVisible(category.isVisible()); + categoryService.saveOrUpdate(c); + } catch (Exception e) { + throw new ServiceRuntimeException("Error while getting category [" + category.getId() + "]",e); + } + } + + @Override + public ReadableCategoryList listByProduct(MerchantStore store, Long product, Language language) { + Validate.notNull(product, "Product id must not be null"); + Validate.notNull(store, "Store must not be null"); + + List readableCategories = new ArrayList(); + + List categories = categoryService.getByProductId(product, store); + + readableCategories = categories.stream() + .map(cat -> categoryReadableCategoryConverter.convert(cat, store, language)) + .collect(Collectors.toList()); + + ReadableCategoryList readableList = new ReadableCategoryList(); + readableList.setCategories(readableCategories); + readableList.setTotalPages(1); + readableList.setNumber(readableCategories.size()); + readableList.setRecordsTotal(readableCategories.size()); + + + return readableList; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/configuration/AbstractConfigurationFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/configuration/AbstractConfigurationFacadeImpl.java new file mode 100644 index 0000000000..418310d9e2 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/configuration/AbstractConfigurationFacadeImpl.java @@ -0,0 +1,6 @@ +package com.salesmanager.shop.store.facade.configuration; + +public abstract class AbstractConfigurationFacadeImpl { + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/content/ContentFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/content/ContentFacadeImpl.java new file mode 100755 index 0000000000..bc2a7acc88 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/content/ContentFacadeImpl.java @@ -0,0 +1,930 @@ +package com.salesmanager.shop.store.facade.content; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; +import org.jsoup.helper.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.content.ContentService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.model.content.Content; +import com.salesmanager.core.model.content.ContentDescription; +import com.salesmanager.core.model.content.ContentType; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.InputContentFile; +import com.salesmanager.core.model.content.OutputContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.content.ContentDescriptionEntity; +import com.salesmanager.shop.model.content.ContentFile; +import com.salesmanager.shop.model.content.ContentFolder; +import com.salesmanager.shop.model.content.ContentImage; +import com.salesmanager.shop.model.content.ReadableContentEntity; +import com.salesmanager.shop.model.content.ReadableContentFull; +import com.salesmanager.shop.model.content.box.PersistableContentBox; +import com.salesmanager.shop.model.content.box.ReadableContentBox; +import com.salesmanager.shop.model.content.box.ReadableContentBoxFull; +import com.salesmanager.shop.model.content.page.PersistableContentPage; +import com.salesmanager.shop.model.content.page.ReadableContentPage; +import com.salesmanager.shop.model.content.page.ReadableContentPageFull; +import com.salesmanager.shop.model.entity.ReadableEntityList; +import com.salesmanager.shop.store.api.exception.ConstraintException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.content.facade.ContentFacade; +import com.salesmanager.shop.utils.FilePathUtils; +import com.salesmanager.shop.utils.ImageFilePath; + +@Component("contentFacade") +public class ContentFacadeImpl implements ContentFacade { + + private static final Logger LOGGER = LoggerFactory.getLogger(ContentFacade.class); + + public static final String FILE_CONTENT_DELIMETER = "/"; + + @Inject + private ContentService contentService; + + @Inject + private LanguageService languageService; + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + @Inject + private FilePathUtils fileUtils; + + @Override + public ContentFolder getContentFolder(String folder, MerchantStore store) throws Exception { + try { + List imageNames = Optional + .ofNullable(contentService.getContentFilesNames(store.getCode(), FileContentType.IMAGE)) + .orElseThrow(() -> new ResourceNotFoundException("No Folder found for path : " + folder)); + + // images from CMS + List contentImages = imageNames.stream().map(name -> convertToContentImage(name, store)) + .collect(Collectors.toList()); + + ContentFolder contentFolder = new ContentFolder(); + if (!StringUtils.isBlank(folder)) { + contentFolder.setPath(URLEncoder.encode(folder, "UTF-8")); + } + contentFolder.getContent().addAll(contentImages); + return contentFolder; + + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while getting folder " + e.getMessage(), e); + } + } + + private ContentImage convertToContentImage(String name, MerchantStore store) { + String path = absolutePath(store, null); + ContentImage contentImage = new ContentImage(); + contentImage.setName(name); + contentImage.setPath(path); + return contentImage; + } + + @Override + public String absolutePath(MerchantStore store, String file) { + return new StringBuilder().append(imageUtils.getContextPath()) + .append(imageUtils.buildStaticImageUtils(store, file)).toString(); + } + + @Override + public void delete(MerchantStore store, String fileName, String fileType) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(fileName, "File name cannot be null"); + try { + FileContentType t = FileContentType.valueOf(fileType); + contentService.removeFile(store.getCode(), t, fileName); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + } + + @SuppressWarnings("unchecked") + @Override + public ReadableEntityList getContentPages(MerchantStore store, Language language, int page, + int count) { + Validate.notNull(store, "MerchantStore cannot be null"); + + @SuppressWarnings("rawtypes") + ReadableEntityList items = new ReadableEntityList(); + Page contentPages; + try { + contentPages = contentService.listByType(ContentType.PAGE, store, page, count); + + items.setTotalPages(contentPages.getTotalPages()); + items.setNumber(contentPages.getContent().size()); + items.setRecordsTotal(contentPages.getNumberOfElements()); + + List boxes = contentPages.getContent().stream() + .map(content -> convertContentToReadableContentBox(store, language, content)) + .collect(Collectors.toList()); + + items.setItems(boxes); + return items; + + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while getting content ", e); + } + + } + + private ReadableContentPage contentDescriptionToReadableContent(MerchantStore store, Content content, + ContentDescription contentDescription) { + + ReadableContentPage page = new ReadableContentPage(); + + ContentDescription desc = new ContentDescription(); + + desc.setName(contentDescription.getName()); + desc.setDescription(contentDescription.getDescription()); + + page.setId(content.getId()); + desc.setSeUrl(contentDescription.getSeUrl()); + page.setLinkToMenu(content.isLinkToMenu()); + desc.setTitle(contentDescription.getTitle()); + desc.setMetatagDescription(contentDescription.getMetatagDescription()); + page.setContentType(ContentType.PAGE.name()); + page.setCode(content.getCode()); + page.setPath(fileUtils.buildStaticFilePath(store.getCode(), contentDescription.getSeUrl())); + return page; + + } + + @Deprecated + private ReadableContentFull convertContentToReadableContentFull(MerchantStore store, Language language, + Content content) { + ReadableContentFull contentFull = new ReadableContentFull(); + + try { + List descriptions = this.createContentDescriptionEntitys(store, content, + language); + + contentFull.setDescriptions(descriptions); + contentFull.setId(content.getId()); + contentFull.setDisplayedInMenu(content.isLinkToMenu()); + contentFull.setContentType(content.getContentType().name()); + contentFull.setCode(content.getCode()); + contentFull.setId(content.getId()); + contentFull.setVisible(content.isVisible()); + + return contentFull; + + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while creating ReadableContentFull", e); + } + } + + @Deprecated + private ReadableContentEntity convertContentToReadableContentEntity(MerchantStore store, Language language, + Content content) { + + ReadableContentEntity contentEntity = new ReadableContentEntity(); + + ContentDescriptionEntity description = this.create(content.getDescription()); + + contentEntity.setDescription(description); + contentEntity.setId(content.getId()); + contentEntity.setDisplayedInMenu(content.isLinkToMenu()); + contentEntity.setContentType(content.getContentType().name()); + contentEntity.setCode(content.getCode()); + contentEntity.setId(content.getId()); + contentEntity.setVisible(content.isVisible()); + + return contentEntity; + + } + + private Content convertContentPageToContent(MerchantStore store, Content model, PersistableContentPage content) throws Exception { + + + + Content contentModel = new Content(); + if(model != null) { + contentModel = model; + } + + List descriptions = buildDescriptions(contentModel, content.getDescriptions()); + contentModel.setCode(content.getCode()); + contentModel.setContentType(ContentType.PAGE); + contentModel.setMerchantStore(store); + contentModel.setLinkToMenu(content.isLinkToMenu()); + contentModel.setVisible(content.isVisible()); + contentModel.setDescriptions(descriptions); + contentModel.setId(content.getId()); + return contentModel; + } + + private Content convertContentBoxToContent(MerchantStore store, Content model, PersistableContentBox content) throws Exception { + Content contentModel = new Content(); + if(model != null) { + contentModel = model; + } + + List descriptions = buildDescriptions(contentModel, content.getDescriptions()); + for(ContentDescription cd : descriptions) { + cd.setContent(contentModel); + } + + contentModel.setCode(content.getCode()); + contentModel.setContentType(ContentType.BOX); + contentModel.setMerchantStore(store); + contentModel.setVisible(content.isVisible()); + contentModel.setDescriptions(descriptions); + contentModel.setId(content.getId()); + return contentModel; + } + + /* + * private Content convertContentPageToContent(MerchantStore store, Language + * language, Content content, PersistableContentEntity contentPage) throws + * ServiceException { + * + * ContentType contentType = + * ContentType.valueOf(contentPage.getContentType()); if (contentType == + * null) { throw new + * ServiceRuntimeException("Invalid specified contentType [" + + * contentPage.getContentType() + "]"); } + * + * List descriptions = createContentDescription(store, + * content, contentPage); descriptions.stream().forEach(c -> + * c.setContent(content)); + * + * content.setDescriptions(descriptions); + * + * // ContentDescription contentDescription = // + * createContentDescription(store, contentPage, language); // + * setContentDescriptionToContentModel(content,contentDescription,language); + * + * // contentDescription.setContent(content); + * + * if (contentPage.getId() != null && contentPage.getId().longValue() > 0) { + * content.setId(contentPage.getId()); } + * content.setVisible(contentPage.isVisible()); + * content.setLinkToMenu(contentPage.isDisplayedInMenu()); + * content.setContentType(ContentType.valueOf(contentPage.getContentType())) + * ; content.setMerchantStore(store); + * + * return content; } + */ + + @Deprecated + private List createContentDescriptionEntitys(MerchantStore store, Content contentModel, + Language language) throws ServiceException { + + List descriptions = new ArrayList(); + + if (!CollectionUtils.isEmpty(contentModel.getDescriptions())) { + for (ContentDescription description : contentModel.getDescriptions()) { + if (language != null && !language.getId().equals(description.getLanguage().getId())) { + continue; + } + + ContentDescriptionEntity contentDescription = create(description); + descriptions.add(contentDescription); + } + } + + return descriptions; + } + + @Deprecated + private ContentDescriptionEntity create(ContentDescription description) { + + ContentDescriptionEntity contentDescription = new ContentDescriptionEntity(); + contentDescription.setLanguage(description.getLanguage().getCode()); + contentDescription.setTitle(description.getTitle()); + contentDescription.setName(description.getName()); + contentDescription.setFriendlyUrl(description.getSeUrl()); + contentDescription.setDescription(description.getDescription()); + if (description.getId() != null && description.getId().longValue() > 0) { + contentDescription.setId(description.getId()); + } + + return contentDescription; + + } + + /* + * private List createContentDescription( + * PersistableContentPage content) throws ServiceException { + * Validate.notNull(contentModel, "Content cannot be null"); + * + * List descriptions = new + * ArrayList(); for (NamedEntity objectContent : + * content.getDescriptions()) { Language lang = + * languageService.getByCode(objectContent.getLanguage()); + * ContentDescription contentDescription = new ContentDescription(); if + * (contentModel != null) { + * setContentDescriptionToContentModel(contentModel, contentDescription, + * lang); } contentDescription.setLanguage(lang); + * contentDescription.setMetatagDescription(objectContent.getMetaDescription + * ()); contentDescription.setTitle(objectContent.getTitle()); + * contentDescription.setName(objectContent.getName()); + * contentDescription.setSeUrl(objectContent.getFriendlyUrl()); + * contentDescription.setDescription(objectContent.getDescription()); + * contentDescription.setMetatagTitle(objectContent.getTitle()); + * descriptions.add(contentDescription); } return descriptions; } + */ + private List buildDescriptions(Content contentModel, + List persistableDescriptions) + throws Exception { + List descriptions = new ArrayList(); + for (com.salesmanager.shop.model.content.common.ContentDescription objectContent : persistableDescriptions) { + Language lang = languageService.getByCode(objectContent.getLanguage()); + Validate.notNull(lang, "language cannot be null"); + ContentDescription contentDescription = null; + if(!CollectionUtils.isEmpty(contentModel.getDescriptions())) { + for(ContentDescription descriptionModel : contentModel.getDescriptions()) { + if(descriptionModel.getLanguage().getCode().equals(lang.getCode())) { + contentDescription = descriptionModel; + break; + } + } + } + + if(contentDescription == null) { + contentDescription = new ContentDescription(); + } + + //if (contentModel != null) { + // setContentDescriptionToContentModel(contentModel, contentDescription, lang); + //} + contentDescription.setMetatagDescription(objectContent.getMetaDescription()); + contentDescription.setTitle(objectContent.getTitle()); + contentDescription.setName(objectContent.getName()); + contentDescription.setSeUrl(objectContent.getFriendlyUrl()); + contentDescription.setDescription(objectContent.getDescription()); + contentDescription.setMetatagTitle(objectContent.getTitle()); + contentDescription.setContent(contentModel); + contentDescription.setLanguage(lang); + descriptions.add(contentDescription); + //contentDescription.setId(objectContent.getId()); + /** + contentDescription.setMetatagDescription(objectContent.getMetaDescription()); + contentDescription.setTitle(objectContent.getTitle()); + contentDescription.setName(objectContent.getName()); + contentDescription.setSeUrl(objectContent.getFriendlyUrl()); + contentDescription.setDescription(objectContent.getDescription()); + contentDescription.setMetatagTitle(objectContent.getTitle()); + descriptions.add(contentDescription); + **/ + } + return descriptions; + } + + private void setContentDescriptionToContentModel(Content content, ContentDescription contentDescription, + Language language) { + + Optional contentDescriptionModel = findAppropriateContentDescription( + content.getDescriptions(), language); + + if (contentDescriptionModel.isPresent()) { + contentDescription.setMetatagDescription(contentDescriptionModel.get().getMetatagDescription()); + contentDescription.setDescription(contentDescriptionModel.get().getDescription()); + contentDescription.setId(contentDescriptionModel.get().getId()); + contentDescription.setAuditSection(contentDescriptionModel.get().getAuditSection()); + contentDescription.setLanguage(contentDescriptionModel.get().getLanguage()); + contentDescription.setTitle(contentDescriptionModel.get().getTitle()); + contentDescription.setName(contentDescriptionModel.get().getName()); + } + + } + + @Override + public ReadableContentPage getContentPage(String code, MerchantStore store, Language language) { + + Validate.notNull(code, "Content code cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + + try { + Content content = null; + + if (language == null) { + content = Optional.ofNullable(contentService.getByCode(code, store)) + .orElseThrow(() -> new ResourceNotFoundException("No page found : " + code)); + } else { + content = Optional.ofNullable(contentService.getByCode(code, store, language)) + .orElseThrow(() -> new ResourceNotFoundException("No page found : " + code)); + } + + return convertContentToReadableContentPage(store, language, content); + + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while getting page " + e.getMessage(), e); + } + } + + @Override + public ReadableEntityList getContentBoxes(ContentType type, String codePrefix, + MerchantStore store, Language language, int page, int count) { + + Validate.notNull(codePrefix, "content code prefix cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + + /* + * return contentService.getByCodeLike(type, codePrefix, store, + * language).stream() .map(content -> + * convertContentToReadableContentBox(store, language, content)) + * .collect(Collectors.toList()); + */ + + return null; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public ReadableEntityList getContentBoxes(ContentType type, MerchantStore store, + Language language, int page, int count) { + + Validate.notNull(store, "MerchantStore cannot be null"); + + ReadableEntityList items = new ReadableEntityList(); + Page contentBoxes; + try { + contentBoxes = contentService.listByType(type, store, page, count); + + items.setTotalPages(contentBoxes.getTotalPages()); + items.setNumber(contentBoxes.getContent().size()); + items.setRecordsTotal(contentBoxes.getNumberOfElements()); + + List boxes = contentBoxes.getContent().stream() + .map(content -> convertContentToReadableContentBox(store, language, content)) + .collect(Collectors.toList()); + + items.setItems(boxes); + + return items; + + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while getting content ", e); + } + + } + + @Override + public void addContentFile(ContentFile file, String merchantStoreCode) { + try { + byte[] payload = file.getFile(); + String fileName = file.getName(); + + try (InputStream targetStream = new ByteArrayInputStream(payload)) { + + String type = file.getContentType().split(FILE_CONTENT_DELIMETER)[0]; + FileContentType fileType = getFileContentType(type); + + InputContentFile cmsContent = new InputContentFile(); + cmsContent.setFileName(fileName); + cmsContent.setMimeType(file.getContentType()); + cmsContent.setFile(targetStream); + cmsContent.setFileContentType(fileType); + + contentService.addContentFile(merchantStoreCode, cmsContent); + } + } catch (ServiceException | IOException e) { + throw new ServiceRuntimeException(e); + } + } + + private FileContentType getFileContentType(String type) { + FileContentType fileType = FileContentType.STATIC_FILE; + if (type.equals("image")) {// for now we consider this route from api + // only + fileType = FileContentType.API_IMAGE; + } + return fileType; + } + + private ReadableContentBox convertContentToReadableContentBox(MerchantStore store, Language language, + Content content) { + if (language != null) { + ReadableContentBox box = new ReadableContentBox(); + this.setDescription(content, box, language); + box.setCode(content.getCode()); + box.setId(content.getId()); + box.setVisible(content.isVisible()); + return box; + } else { + ReadableContentBoxFull box = new ReadableContentBoxFull(); + List descriptions = content.getDescriptions() + .stream().map(d -> this.contentDescription(d)).collect(Collectors.toList()); + this.setDescription(content, box, store.getDefaultLanguage()); + box.setDescriptions(descriptions); + box.setCode(content.getCode()); + box.setId(content.getId()); + box.setVisible(content.isVisible()); + return box; + } + // TODO revise this + // String staticImageFilePath = imageUtils.buildStaticImageUtils(store, + // content.getCode() + ".jpg"); + // box.setImage(staticImageFilePath); + } + + private void setDescription(Content content, ReadableContentBox box, Language lang) { + + Optional contentDescription = findAppropriateContentDescription( + content.getDescriptions(), lang); + if (contentDescription.isPresent()) { + com.salesmanager.shop.model.content.common.ContentDescription desc = this + .contentDescription(contentDescription.get()); + box.setDescription(desc); + } + + } + + private ReadableContentPage convertContentToReadableContentPage(MerchantStore store, Language language, + Content content) { + if (language != null) { + ReadableContentPage page = new ReadableContentPage(); + Optional contentDescription = findAppropriateContentDescription( + content.getDescriptions(), language); + if (contentDescription.isPresent()) { + com.salesmanager.shop.model.content.common.ContentDescription desc = this + .contentDescription(contentDescription.get()); + page.setDescription(desc); + } + page.setCode(content.getCode()); + page.setId(content.getId()); + page.setVisible(content.isVisible()); + return page; + } else { + ReadableContentPageFull page = new ReadableContentPageFull(); + List descriptions = content.getDescriptions() + .stream().map(d -> this.contentDescription(d)).collect(Collectors.toList()); + page.setDescriptions(descriptions); + page.setCode(content.getCode()); + page.setId(content.getId()); + page.setVisible(content.isVisible()); + return page; + } + + } + + private com.salesmanager.shop.model.content.common.ContentDescription contentDescription( + ContentDescription description) { + Validate.notNull(description, "ContentDescription cannot be null"); + com.salesmanager.shop.model.content.common.ContentDescription desc = new com.salesmanager.shop.model.content.common.ContentDescription(); + desc.setDescription(description.getDescription());//return description as is + desc.setName(description.getName()); + desc.setTitle(description.getTitle()); + desc.setFriendlyUrl(description.getSeUrl()); + desc.setId(description.getId()); + desc.setLanguage(description.getLanguage().getCode()); + return desc; + } + + private ReadableContentBox convertContentToReadableLegacyContentBox(MerchantStore store, Language language, + Content content) { + /* + * ReadableContentBox box = new ReadableContentBox(); + * Optional contentDescription = + * findAppropriateContentDescription(content.getDescriptions(), + * language); if (contentDescription.isPresent()) { + * box.setName(contentDescription.get().getName()); + * box.setBoxContent(contentDescription.get().getDescription()); } + * String staticImageFilePath = imageUtils.buildStaticImageUtils(store, + * content.getCode() + ".jpg"); box.setImage(staticImageFilePath); + * return box; + */ + + return null; + } + + private Optional findAppropriateContentDescription(List contentDescriptions, + Language language) { + return contentDescriptions.stream() + .filter(description -> description.getLanguage().getCode().equals(language.getCode())).findFirst(); + } + + @Override + public ReadableContentBox getContentBox(String code, MerchantStore store, Language language) { + Validate.notNull(code, "Content code cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + + try { + Content content = null; + ReadableContentBox box = new ReadableContentBox(); + + if(language != null) { + + content = Optional.ofNullable(contentService.getByCode(code, store, language)) + .orElseThrow(() -> new ResourceNotFoundException( + "Resource not found [" + code + "] for store [" + store.getCode() + "]")); + + Optional contentDescription = findAppropriateContentDescription( + content.getDescriptions(), language); + + if (contentDescription.isPresent()) { + com.salesmanager.shop.model.content.common.ContentDescription desc = this + .contentDescription(contentDescription.get());//return cdata description + desc.setDescription(this.fixContentDescription(desc.getDescription())); + box.setDescription(desc); + } + + return box; + + } else { + + content = Optional.ofNullable(contentService.getByCode(code, store)) + .orElseThrow(() -> new ResourceNotFoundException( + "Resource not found [" + code + "] for store [" + store.getCode() + "]")); + + ReadableContentBoxFull full = new ReadableContentBoxFull(); //all languages + + List descriptions = content.getDescriptions() + .stream().map(d -> this.contentDescription(d)).collect(Collectors.toList()); + + /** + Optional contentDescription = findAppropriateContentDescription( + content.getDescriptions(), store.getDefaultLanguage()); + + if(contentDescription.isPresent()) { + com.salesmanager.shop.model.content.common.ContentDescription desc = this + .contentDescription(contentDescription.get()); + full.setDescription(desc); + } + **/ + + + full.setDescriptions(descriptions); + full.setCode(content.getCode()); + full.setId(content.getId()); + full.setVisible(content.isVisible()); + + return full; + + } + + + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + } + + private String fixContentDescription(String description) { + Validate.notNull(description, "description cannot be empty"); + return ""; + + + } + + @Override + public Long saveContentPage(PersistableContentPage page, MerchantStore merchantStore, Language language) { + Validate.notNull(page); + Validate.notNull(page.getCode(), "Content code must not be null"); + Validate.notNull(merchantStore); + + try { + Content content = null; + + content = contentService.getByCode(page.getCode(), merchantStore); + if (content != null) { + throw new ConstraintException("Page with code [" + page.getCode() + "] already exist for store [" + + merchantStore.getCode() + "]"); + } + + content = convertContentPageToContent(merchantStore, content, page); + contentService.saveOrUpdate(content); + return content.getId(); + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + } + + @Override + public Long saveContentBox(PersistableContentBox box, MerchantStore merchantStore, Language language) { + Validate.notNull(box); + Validate.notNull(box.getCode(), "Content box must not be null"); + Validate.notNull(merchantStore); + + try { + Content content = null; + + content = contentService.getByCode(box.getCode(), merchantStore); + if (content != null) { + throw new ConstraintException("Content box with code [" + box.getCode() + "] already exist for store [" + + merchantStore.getCode() + "]"); + } + + content = convertContentBoxToContent(merchantStore, content, box); + contentService.saveOrUpdate(content); + return content.getId(); + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + + } + + @Override + public void addContentFiles(List files, String merchantStoreCode) { + for (ContentFile file : files) { + addContentFile(file, merchantStoreCode); + } + + } + + @Override + public void delete(MerchantStore store, Long id) { + Validate.notNull(store, "MerchantStore not null"); + Validate.notNull(id, "Content id must not be null"); + // select content first + Content content = contentService.getById(id); + if (content != null) { + if (content.getMerchantStore().getId().intValue() != store.getId().intValue()) { + throw new ResourceNotFoundException( + "No content found with id [" + id + "] for store [" + store.getCode() + "]"); + } + } + + try { + contentService.delete(content); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while deleting content " + e.getMessage(), e); + } + + } + + @Override + public ReadableContentFull getContent(String code, MerchantStore store, Language language) { + Validate.notNull(store, "MerchantStore not null"); + Validate.notNull(code, "Content code must not be null"); + + try { + Content content = contentService.getByCode(code, store); + if (content == null) { + throw new ResourceNotFoundException( + "No content found with code [" + code + "] for store [" + store.getCode() + "]"); + } + + return this.convertContentToReadableContentFull(store, language, content); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while getting content [" + code + "]", e); + } + + } + + @Override + public List getContents(Optional type, MerchantStore store, Language language) { + + /** + * get all types + */ + List types = new ArrayList(); + types.add(ContentType.BOX); + types.add(ContentType.PAGE); + types.add(ContentType.SECTION); + + try { + return contentService.listByType(types, store, language).stream() + .map(content -> convertContentToReadableContentEntity(store, language, content)) + .collect(Collectors.toList()); + + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while getting contents", e); + } + + } + + @Override + public ReadableContentPage getContentPageByName(String name, MerchantStore store, Language language) { + Validate.notNull(name, "Content name cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + + try { + + ContentDescription contentDescription = Optional.ofNullable(contentService.getBySeUrl(store, name)) + .orElseThrow(() -> new ResourceNotFoundException("No page found : " + name)); + + return this.contentDescriptionToReadableContent(store, contentDescription.getContent(), contentDescription); + + } catch (Exception e) { + throw new ServiceRuntimeException("Error while getting page " + e.getMessage(), e); + } + } + + @Override + public void renameFile(MerchantStore store, FileContentType fileType, String originalName, String newName) { + Optional path = Optional.ofNullable(null); + try { + contentService.renameFile(store.getCode(), fileType, path, originalName, newName); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while renaming file " + e.getMessage(), e); + } + + } + + @Override + public OutputContentFile download(MerchantStore store, FileContentType fileType, String fileName) { + + try { + return contentService.getContentFile(store.getCode(), fileType, fileName); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while downloading file " + e.getMessage(), e); + } + + } + + + + @Override + public void updateContentPage(Long id, PersistableContentPage page, MerchantStore merchantStore, + Language language) { + Validate.notNull(page); + Validate.notNull(id, "Content id must not be null"); + Validate.notNull(merchantStore); + + try { + Content content = null; + + content = contentService.getById(id, merchantStore); + if (content == null) { + throw new ConstraintException("Page with id [" + id + "] does not exist for store [" + + merchantStore.getCode() + "]"); + } + + page.setId(id); + content = convertContentPageToContent(merchantStore, content, page); + contentService.saveOrUpdate(content); + + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + + } + + @Override + public void deleteContent(Long id, MerchantStore merchantStore) { + Validate.notNull(id, "Content id must not be null"); + Validate.notNull(merchantStore); + + try { + Content content = null; + + content = contentService.getById(id, merchantStore); + if (content == null) { + throw new ConstraintException("Content with id [" + id + "] does not exist for store [" + + merchantStore.getCode() + "]"); + } + + contentService.delete(content); + + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + + } + + @Override + public void updateContentBox(Long id, PersistableContentBox box, MerchantStore merchantStore, Language language) { + Validate.notNull(box); + Validate.notNull(id, "Content id must not be null"); + Validate.notNull(merchantStore); + + try { + Content content = null; + + content = contentService.getById(id, merchantStore); + if (content == null) { + throw new ConstraintException("Page with id [" + id + "] does not exist for store [" + + merchantStore.getCode() + "]"); + } + + box.setId(id); + content = convertContentBoxToContent(merchantStore, content, box); + contentService.saveOrUpdate(content); + + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + + } + + @Override + public boolean codeExist(String code, String type, MerchantStore store) { + return contentService.exists(code, ContentType.valueOf(type), store); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/customer/CustomerFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/customer/CustomerFacadeImpl.java new file mode 100644 index 0000000000..9748865bba --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/customer/CustomerFacadeImpl.java @@ -0,0 +1,258 @@ +package com.salesmanager.shop.store.facade.customer; + +import java.security.Principal; +import java.util.Date; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +import javax.inject.Inject; + +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.scheduling.annotation.Async; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.email.Email; +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.services.system.EmailService; +import com.salesmanager.core.model.common.CredentialsReset; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.constants.EmailConstants; +import com.salesmanager.shop.store.api.exception.GenericRuntimeException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.api.exception.UnauthorizedException; +import com.salesmanager.shop.store.controller.customer.facade.v1.CustomerFacade; +import com.salesmanager.shop.utils.DateUtil; +import com.salesmanager.shop.utils.EmailUtils; +import com.salesmanager.shop.utils.FilePathUtils; +import com.salesmanager.shop.utils.ImageFilePath; +import com.salesmanager.shop.utils.LabelUtils; + +@Service("customerFacadev1") +public class CustomerFacadeImpl implements CustomerFacade { + + @Autowired + private com.salesmanager.shop.store.controller.customer.facade.CustomerFacade customerFacade; + + @Autowired + private CustomerService customerService; + + @Autowired + private FilePathUtils filePathUtils; + + @Autowired + private LanguageService lamguageService; + + @Autowired + private EmailUtils emailUtils; + + @Autowired + private EmailService emailService; + + @Autowired + @Qualifier("img") + private ImageFilePath imageUtils; + + @Inject + private LabelUtils messages; + + @Inject + private PasswordEncoder passwordEncoder; + + private static final String resetCustomerLink = "customer/%s/reset/%s"; // front + // url + + private static final String ACCOUNT_PASSWORD_RESET_TPL = "email_template_password_reset_request_customer.ftl"; + + private static final String RESET_PASSWORD_LINK = "RESET_PASSWORD_LINK"; + + private static final String RESET_PASSWORD_TEXT = "RESET_PASSWORD_TEXT"; + + @Override + public void authorize(Customer customer, Principal principal) { + + Validate.notNull(customer, "Customer cannot be null"); + Validate.notNull(principal, "Principal cannot be null"); + + if (!principal.getName().equals(customer.getNick())) { + throw new UnauthorizedException( + "User [" + principal.getName() + "] unauthorized for customer [" + customer.getId() + "]"); + } + + } + + @Override + public void requestPasswordReset(String customerName, String customerContextPath, MerchantStore store, + Language language) { + + try { + // get customer by user name + Customer customer = customerService.getByNick(customerName, store.getId()); + + if (customer == null) { + throw new ResourceNotFoundException( + "Customer [" + customerName + "] not found for store [" + store.getCode() + "]"); + } + + // generates unique token + String token = UUID.randomUUID().toString(); + + Date expiry = DateUtil.addDaysToCurrentDate(2); + + CredentialsReset credsRequest = new CredentialsReset(); + credsRequest.setCredentialsRequest(token); + credsRequest.setCredentialsRequestExpiry(expiry); + customer.setCredentialsResetRequest(credsRequest); + + customerService.saveOrUpdate(customer); + + // reset password link + // this will build http | https ://domain/contextPath + String baseUrl = filePathUtils.buildBaseUrl(customerContextPath, store); + + // need to add link to controller receiving user reset password + // request + String customerResetLink = new StringBuilder().append(baseUrl) + .append(String.format(resetCustomerLink, store.getCode(), token)).toString(); + + resetPasswordRequest(customer, customerResetLink, store, lamguageService.toLocale(language, store)); + + } catch (Exception e) { + throw new ServiceRuntimeException("Error while executing resetPassword request", e); + } + + /** + * User sends username (unique in the system) + * + * UserNameEntity will be the following { userName: "test@test.com" } + * + * The system retrieves user using userName (username is unique) if user + * exists, system sends an email with reset password link + * + * How to retrieve a User from userName + * + * userFacade.findByUserName + * + * How to send an email + * + * + * How to generate a token + * + * Generate random token + * + * Calculate token expiration date + * + * Now + 48 hours + * + * Update User in the database with token + * + * Send reset token email + */ + + } + + @Async + private void resetPasswordRequest(Customer customer, String resetLink, MerchantStore store, Locale locale) + throws Exception { + try { + + // creation of a user, send an email + String[] storeEmail = { store.getStoreEmailAddress() }; + + Map templateTokens = emailUtils.createEmailObjectsMap(imageUtils.getContextPath(), store, + messages, locale); + templateTokens.put(EmailConstants.LABEL_HI, messages.getMessage("label.generic.hi", locale)); + templateTokens.put(EmailConstants.EMAIL_CUSTOMER_FIRSTNAME, customer.getBilling().getFirstName()); + templateTokens.put(RESET_PASSWORD_LINK, resetLink); + templateTokens.put(RESET_PASSWORD_TEXT, + messages.getMessage("email.reset.password.text", new String[] { store.getStorename() }, locale)); + templateTokens.put(EmailConstants.LABEL_LINK_TITLE, + messages.getMessage("email.link.reset.password.title", locale)); + templateTokens.put(EmailConstants.LABEL_LINK, messages.getMessage("email.link", locale)); + templateTokens.put(EmailConstants.EMAIL_CONTACT_OWNER, + messages.getMessage("email.contactowner", storeEmail, locale)); + + Email email = new Email(); + email.setFrom(store.getStorename()); + email.setFromEmail(store.getStoreEmailAddress()); + email.setSubject(messages.getMessage("email.link.reset.password.title", locale)); + email.setTo(customer.getEmailAddress()); + email.setTemplateName(ACCOUNT_PASSWORD_RESET_TPL); + email.setTemplateTokens(templateTokens); + + emailService.sendHtmlEmail(store, email); + + } catch (Exception e) { + throw new Exception("Cannot send email to customer", e); + } + } + + @Override + public void verifyPasswordRequestToken(String token, String store) { + Validate.notNull(token, "ResetPassword token cannot be null"); + Validate.notNull(store, "Store code cannot be null"); + + verifyCustomerLink(token, store); + return; + } + + @Override + public void resetPassword(String password, String token, String store) { + Validate.notNull(token, "ResetPassword token cannot be null"); + Validate.notNull(store, "Store code cannot be null"); + Validate.notNull(password, "New password cannot be null"); + + Customer customer = verifyCustomerLink(token, store);// reverify + customer.setPassword(passwordEncoder.encode(password)); + try { + customerService.save(customer); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while saving customer",e); + } + + } + + private Customer verifyCustomerLink(String token, String store) { + + Customer customer = null; + try { + customer = customerService.getByPasswordResetToken(store, token); + if (customer == null) { + throw new ResourceNotFoundException( + "Customer not fount for store [" + store + "] and token [" + token + "]"); + } + + } catch (Exception e) { + throw new ServiceRuntimeException("Cannot verify customer token", e); + } + + Date tokenExpiry = customer.getCredentialsResetRequest().getCredentialsRequestExpiry(); + + if (tokenExpiry == null) { + throw new GenericRuntimeException("No expiry date configured for token [" + token + "]"); + } + + if (!DateUtil.dateBeforeEqualsDate(new Date(), tokenExpiry)) { + throw new GenericRuntimeException("Ttoken [" + token + "] has expired"); + } + + return customer; + + } + + @Override + public boolean customerExists(String userName, MerchantStore store) { + return Optional.ofNullable(customerService.getByNick(userName, store.getId())) + .isPresent(); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/items/ProductItemsFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/items/ProductItemsFacadeImpl.java new file mode 100755 index 0000000000..4b0f6eddca --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/items/ProductItemsFacadeImpl.java @@ -0,0 +1,271 @@ +package com.salesmanager.shop.store.facade.items; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.relationship.ProductRelationshipService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.ProductCriteria; +import com.salesmanager.core.model.catalog.product.relationship.ProductRelationship; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.model.catalog.product.ReadableProductList; +import com.salesmanager.shop.model.catalog.product.group.ProductGroup; +import com.salesmanager.shop.populator.catalog.ReadableProductPopulator; +import com.salesmanager.shop.store.api.exception.OperationNotAllowedException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.items.facade.ProductItemsFacade; +import com.salesmanager.shop.utils.ImageFilePath; + +@Component +public class ProductItemsFacadeImpl implements ProductItemsFacade { + + + @Inject + ProductService productService; + + @Inject + PricingService pricingService; + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + @Inject + private ProductRelationshipService productRelationshipService; + + @Override + public ReadableProductList listItemsByManufacturer(MerchantStore store, + Language language, Long manufacturerId, int startCount, int maxCount) throws Exception { + + + ProductCriteria productCriteria = new ProductCriteria(); + productCriteria.setMaxCount(maxCount); + productCriteria.setStartIndex(startCount); + + + productCriteria.setManufacturerId(manufacturerId); + com.salesmanager.core.model.catalog.product.ProductList products = productService.listByStore(store, language, productCriteria); + + + ReadableProductPopulator populator = new ReadableProductPopulator(); + populator.setPricingService(pricingService); + populator.setimageUtils(imageUtils); + + + ReadableProductList productList = new ReadableProductList(); + for(Product product : products.getProducts()) { + + //create new proxy product + ReadableProduct readProduct = populator.populate(product, new ReadableProduct(), store, language); + productList.getProducts().add(readProduct); + + } + + productList.setTotalPages(Math.toIntExact(products.getTotalCount())); + + + return productList; + } + + @Override + public ReadableProductList listItemsByIds(MerchantStore store, Language language, List ids, int startCount, + int maxCount) throws Exception { + + if(CollectionUtils.isEmpty(ids)) { + return new ReadableProductList(); + } + + + ProductCriteria productCriteria = new ProductCriteria(); + productCriteria.setMaxCount(maxCount); + productCriteria.setStartIndex(startCount); + productCriteria.setProductIds(ids); + + + com.salesmanager.core.model.catalog.product.ProductList products = productService.listByStore(store, language, productCriteria); + + + ReadableProductPopulator populator = new ReadableProductPopulator(); + populator.setPricingService(pricingService); + populator.setimageUtils(imageUtils); + + + ReadableProductList productList = new ReadableProductList(); + for(Product product : products.getProducts()) { + + //create new proxy product + ReadableProduct readProduct = populator.populate(product, new ReadableProduct(), store, language); + productList.getProducts().add(readProduct); + + } + + productList.setNumber(Math.toIntExact(products.getTotalCount())); + productList.setRecordsTotal(new Long(products.getTotalCount())); + + return productList; + } + + @Override + public ReadableProductList listItemsByGroup(String group, MerchantStore store, Language language) throws Exception { + + + //get product group + List groups = productRelationshipService.getByGroup(store, group, language); + + if(group!=null) { + List ids = new ArrayList(); + for(ProductRelationship relationship : groups) { + Product product = relationship.getRelatedProduct(); + ids.add(product.getId()); + } + + ReadableProductList list = listItemsByIds(store, language, ids, 0, 0); + List prds = list.getProducts().stream().sorted(Comparator.comparing(ReadableProduct::getSortOrder)).collect(Collectors.toList()); + list.setProducts(prds); + list.setTotalPages(1);//no paging + return list; + } + + return null; + } + + @Override + public ReadableProductList addItemToGroup(Product product, String group, MerchantStore store, Language language) { + + Validate.notNull(product,"Product must not be null"); + Validate.notNull(group,"group must not be null"); + + + //check if product is already in group + List existList = null; + try { + existList = productRelationshipService.getByGroup(store, group).stream() + .filter(prod -> prod.getRelatedProduct() != null && (product.getId().longValue() == prod.getRelatedProduct().getId())) + .collect(Collectors.toList()); + } catch (ServiceException e) { + throw new ServiceRuntimeException("ExceptionWhile getting product group [" + group + "]", e); + } + + if(existList.size()>0) { + throw new OperationNotAllowedException("Product with id [" + product.getId() + "] is already in the group"); + } + + + ProductRelationship relationship = new ProductRelationship(); + relationship.setActive(true); + relationship.setCode(group); + relationship.setStore(store); + relationship.setRelatedProduct(product); + + try { + productRelationshipService.saveOrUpdate(relationship); + return listItemsByGroup(group,store,language); + } catch (Exception e) { + throw new ServiceRuntimeException("ExceptionWhile getting product group [" + group + "]", e); + } + + + + + } + + @Override + public ReadableProductList removeItemFromGroup(Product product, String group, MerchantStore store, + Language language) throws Exception { + + List relationships = productRelationshipService + .getByType(store, product, group); + + + for(ProductRelationship r : relationships) { + productRelationshipService.delete(r); + } + + return listItemsByGroup(group,store,language); + } + + @Override + public void deleteGroup(String group, MerchantStore store) { + + Validate.notNull(group, "Group cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + + try { + productRelationshipService.deleteGroup(store, group); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Cannor delete product group",e); + } + + } + + @Override + public ProductGroup createProductGroup(ProductGroup group, MerchantStore store) { + Validate.notNull(group,"ProductGroup cannot be null"); + Validate.notNull(group.getCode(),"ProductGroup code cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null"); + try { + productRelationshipService.addGroup(store, group.getCode()); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Cannor delete product group",e); + } + return group; + } + + @Override + public void updateProductGroup(String code, ProductGroup group, MerchantStore store) { + try { + List items = productRelationshipService.getGroupDefinition(store, code); + if(CollectionUtils.isEmpty(items)) { + throw new ResourceNotFoundException("ProductGroup [" + code + "] not found"); + } + + if(group.isActive()) { + productRelationshipService.activateGroup(store, code); + } else { + productRelationshipService.deactivateGroup(store, code); + } + + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while updating product [" + code + "]"); + } + + } + + @Override + public List listProductGroups(MerchantStore store, Language language) { + Validate.notNull(store,"MerchantStore cannot be null"); + + List relationships = productRelationshipService.getGroups(store); + + List groups = new ArrayList(); + + for(ProductRelationship relationship : relationships) { + + ProductGroup g = new ProductGroup(); + g.setActive(relationship.isActive()); + g.setCode(relationship.getCode()); + g.setId(relationship.getId()); + groups.add(g); + + + } + + return groups; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/manufacturer/ManufacturerFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/manufacturer/ManufacturerFacadeImpl.java new file mode 100755 index 0000000000..a03a559cf0 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/manufacturer/ManufacturerFacadeImpl.java @@ -0,0 +1,257 @@ +package com.salesmanager.shop.store.facade.manufacturer; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; +import javax.inject.Inject; +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.category.CategoryService; +import com.salesmanager.core.business.services.catalog.product.manufacturer.ManufacturerService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.Mapper; +import com.salesmanager.shop.model.catalog.manufacturer.PersistableManufacturer; +import com.salesmanager.shop.model.catalog.manufacturer.ReadableManufacturer; +import com.salesmanager.shop.model.catalog.manufacturer.ReadableManufacturerList; +import com.salesmanager.shop.model.entity.ListCriteria; +import com.salesmanager.shop.populator.manufacturer.PersistableManufacturerPopulator; +import com.salesmanager.shop.populator.manufacturer.ReadableManufacturerPopulator; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.api.exception.UnauthorizedException; +import com.salesmanager.shop.store.controller.manufacturer.facade.ManufacturerFacade; + +@Service("manufacturerFacade") +public class ManufacturerFacadeImpl implements ManufacturerFacade { + + @Inject + private Mapper readableManufacturerConverter; + + + @Autowired + private ManufacturerService manufacturerService; + + @Autowired + private CategoryService categoryService; + + @Inject + private LanguageService languageService; + + @Override + public List getByProductInCategory(MerchantStore store, Language language, + Long categoryId) { + Validate.notNull(store,"MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + Validate.notNull(categoryId,"Category id cannot be null"); + + Category category = categoryService.getById(categoryId, store.getId()); + + if(category == null) { + throw new ResourceNotFoundException("Category with id [" + categoryId + "] not found"); + } + + if(category.getMerchantStore().getId().longValue() != store.getId().longValue()) { + throw new UnauthorizedException("Merchant [" + store.getCode() + "] not authorized"); + } + + try { + List manufacturers = manufacturerService.listByProductsInCategory(store, category, language); + + List manufacturersList = manufacturers.stream() + .sorted(new Comparator() { + @Override + public int compare(final Manufacturer object1, final Manufacturer object2) { + return object1.getCode().compareTo(object2.getCode()); + } + }) + .map(manuf -> readableManufacturerConverter.convert(manuf, store, language)) + .collect(Collectors.toList()); + + return manufacturersList; + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + + } + + @Override + public void saveOrUpdateManufacturer(PersistableManufacturer manufacturer, MerchantStore store, + Language language) throws Exception { + + PersistableManufacturerPopulator populator = new PersistableManufacturerPopulator(); + populator.setLanguageService(languageService); + + + Manufacturer manuf = new Manufacturer(); + + if(manufacturer.getId() != null && manufacturer.getId().longValue() > 0) { + manuf = manufacturerService.getById(manufacturer.getId()); + if(manuf == null) { + throw new ResourceNotFoundException("Manufacturer with id [" + manufacturer.getId() + "] not found"); + } + + if(manuf.getMerchantStore().getId().intValue() != store.getId().intValue()) { + throw new ResourceNotFoundException("Manufacturer with id [" + manufacturer.getId() + "] not found for store [" + store.getId() + "]"); + } + } + + populator.populate(manufacturer, manuf, store, language); + + manufacturerService.saveOrUpdate(manuf); + + manufacturer.setId(manuf.getId()); + + } + + @Override + public void deleteManufacturer(Manufacturer manufacturer, MerchantStore store, Language language) + throws Exception { + manufacturerService.delete(manufacturer); + + } + + @Override + public ReadableManufacturer getManufacturer(Long id, MerchantStore store, Language language) + throws Exception { + Manufacturer manufacturer = manufacturerService.getById(id); + + + + if (manufacturer == null) { + throw new ResourceNotFoundException("Manufacturer [" + id + "] not found"); + } + + if(manufacturer.getMerchantStore().getId() != store.getId()) { + throw new ResourceNotFoundException("Manufacturer [" + id + "] not found for store [" + store.getId() + "]"); + } + + ReadableManufacturer readableManufacturer = new ReadableManufacturer(); + + ReadableManufacturerPopulator populator = new ReadableManufacturerPopulator(); + readableManufacturer = populator.populate(manufacturer, readableManufacturer, store, language); + + + return readableManufacturer; + } + + @Override + public ReadableManufacturerList getAllManufacturers(MerchantStore store, Language language, ListCriteria criteria, int page, int count) { + + ReadableManufacturerList readableList = new ReadableManufacturerList(); + try { + /** + * Is this a pageable request + */ + + List manufacturers = null; + if(page == 0 && count == 0) { + //need total count + int total = manufacturerService.count(store); + + if(language != null) { + manufacturers = manufacturerService.listByStore(store, language); + } else { + manufacturers = manufacturerService.listByStore(store); + } + readableList.setRecordsTotal(total); + readableList.setNumber(manufacturers.size()); + } else { + + Page m = null; + if(language != null) { + m = manufacturerService.listByStore(store, language, criteria.getName(), page, count); + } else { + m = manufacturerService.listByStore(store, criteria.getName(), page, count); + } + manufacturers = m.getContent(); + readableList.setTotalPages(m.getTotalPages()); + readableList.setRecordsTotal(m.getTotalElements()); + readableList.setNumber(m.getNumber()); + } + + + ReadableManufacturerPopulator populator = new ReadableManufacturerPopulator(); + List returnList = new ArrayList(); + + for (Manufacturer m : manufacturers) { + ReadableManufacturer readableManufacturer = new ReadableManufacturer(); + populator.populate(m, readableManufacturer, store, language); + returnList.add(readableManufacturer); + } + + readableList.setManufacturers(returnList); + return readableList; + + } catch (Exception e) { + throw new ServiceRuntimeException("Error while get manufacturers",e); + } + } + + + @Override + public boolean manufacturerExist(MerchantStore store, String manufacturerCode) { + Validate.notNull(store,"Store must not be null"); + Validate.notNull(manufacturerCode,"Manufacturer code must not be null"); + boolean exists = false; + Manufacturer manufacturer = manufacturerService.getByCode(store, manufacturerCode); + if(manufacturer!=null) { + exists = true; + } + return exists; + } + +@Override +public ReadableManufacturerList listByStore(MerchantStore store, Language language, ListCriteria criteria, int page, + int count) { + + ReadableManufacturerList readableList = new ReadableManufacturerList(); + + try { + /** + * Is this a pageable request + */ + + List manufacturers = null; + + Page m = null; + if(language != null) { + m = manufacturerService.listByStore(store, language, criteria.getName(), page, count); + } else { + m = manufacturerService.listByStore(store, criteria.getName(), page, count); + } + + manufacturers = m.getContent(); + readableList.setTotalPages(m.getTotalPages()); + readableList.setRecordsTotal(m.getTotalElements()); + readableList.setNumber(m.getContent().size()); + + + + ReadableManufacturerPopulator populator = new ReadableManufacturerPopulator(); + List returnList = new ArrayList(); + + for (Manufacturer mf : manufacturers) { + ReadableManufacturer readableManufacturer = new ReadableManufacturer(); + populator.populate(mf, readableManufacturer, store, language); + returnList.add(readableManufacturer); + } + + readableList.setManufacturers(returnList); + return readableList; + + } catch (Exception e) { + throw new ServiceRuntimeException("Error while get manufacturers",e); + } + +} + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/order/OrderFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/order/OrderFacadeImpl.java new file mode 100644 index 0000000000..7893a017c3 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/order/OrderFacadeImpl.java @@ -0,0 +1,130 @@ +package com.salesmanager.shop.store.facade.order; + +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.order.OrderTotal; +import com.salesmanager.core.model.order.orderproduct.OrderProduct; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.customer.ReadableCustomerMapper; +import com.salesmanager.shop.mapper.order.ReadableOrderProductMapper; +import com.salesmanager.shop.mapper.order.ReadableOrderTotalMapper; +import com.salesmanager.shop.model.customer.ReadableCustomer; +import com.salesmanager.shop.model.order.ReadableOrderProduct; +import com.salesmanager.shop.model.order.total.ReadableOrderTotal; +import com.salesmanager.shop.model.order.total.ReadableTotal; +import com.salesmanager.shop.model.order.v1.ReadableOrderConfirmation; +import com.salesmanager.shop.store.controller.order.facade.v1.OrderFacade; +import com.salesmanager.shop.utils.LabelUtils; + +@Service("orderFacadev1") +public class OrderFacadeImpl implements OrderFacade { + + private static final Logger LOGGER = LoggerFactory.getLogger(OrderFacadeImpl.class); + + + @Autowired + private ReadableCustomerMapper readableCustomerMapper; + + @Autowired + private ReadableOrderTotalMapper readableOrderTotalMapper; + + @Autowired + private ReadableOrderProductMapper readableOrderProductMapper; + + @Autowired + private LabelUtils messages; + + @Autowired + private LanguageService languageService; + + @Override + public ReadableOrderConfirmation orderConfirmation(Order order, Customer customer, MerchantStore store, + Language language) { + Validate.notNull(order, "Order cannot be null"); + Validate.notNull(customer, "Customer cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + + ReadableOrderConfirmation orderConfirmation = new ReadableOrderConfirmation(); + + ReadableCustomer readableCustomer = readableCustomerMapper.convert(customer, store, language); + orderConfirmation.setBilling(readableCustomer.getBilling()); + orderConfirmation.setDelivery(readableCustomer.getDelivery()); + + ReadableTotal readableTotal = new ReadableTotal(); + + Set totals = order.getOrderTotal(); + List readableTotals = totals.stream() + .sorted(Comparator.comparingInt(OrderTotal::getSortOrder)) + .map(tot -> convertOrderTotal(tot, store, language)) + .collect(Collectors.toList()); + + readableTotal.setTotals(readableTotals); + + + Optional grandTotal = readableTotals.stream().filter(tot -> tot.getCode().equals("order.total.total")).findFirst(); + + + if(grandTotal.isPresent()) { + readableTotal.setGrandTotal(grandTotal.get().getText()); + } + orderConfirmation.setTotal(readableTotal); + + + List products = order.getOrderProducts().stream().map(pr -> convertOrderProduct(pr, store, language)).collect(Collectors.toList()); + orderConfirmation.setProducts(products); + + if(!StringUtils.isBlank(order.getShippingModuleCode())) { + StringBuilder optionCodeBuilder = new StringBuilder(); + try { + + optionCodeBuilder + .append("module.shipping.") + .append(order.getShippingModuleCode()); + String shippingName = messages.getMessage(optionCodeBuilder.toString(), new String[]{store.getStorename()},languageService.toLocale(language, store)); + orderConfirmation.setShipping(shippingName); + } catch (Exception e) { // label not found + LOGGER.warn("No shipping code found for " + optionCodeBuilder.toString()); + } + } + + if(order.getPaymentType() != null) { + orderConfirmation.setPayment(order.getPaymentType().name()); + } + + + /** + * Confirmation may be formatted + */ + orderConfirmation.setId(order.getId()); + + + return orderConfirmation; + } + + private ReadableOrderTotal convertOrderTotal(OrderTotal total, MerchantStore store, Language language) { + + return readableOrderTotalMapper.convert(total, store, language); + } + + private ReadableOrderProduct convertOrderProduct(OrderProduct product, MerchantStore store, Language language) { + + return readableOrderProductMapper.convert(product, store, language); + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/payment/PaymentConfigurationFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/payment/PaymentConfigurationFacadeImpl.java new file mode 100644 index 0000000000..364d7053f2 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/payment/PaymentConfigurationFacadeImpl.java @@ -0,0 +1,95 @@ +package com.salesmanager.shop.store.facade.payment; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.payments.PaymentService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.payments.PaymentMethod; +import com.salesmanager.core.model.system.IntegrationConfiguration; +import com.salesmanager.shop.model.configuration.PersistableConfiguration; +import com.salesmanager.shop.model.configuration.ReadableConfiguration; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.configurations.ConfigurationsFacade; + + +@Service("paymentConfigurationFacade") +public class PaymentConfigurationFacadeImpl implements ConfigurationsFacade { + + + @Autowired + private PaymentService paymentService; + + @Override + public List configurations(MerchantStore store) { + + try { + + List methods = paymentService.getAcceptedPaymentMethods(store); + List configurations = + methods.stream() + .map(m -> configuration(m.getInformations(), store)).collect(Collectors.toList()); + return configurations; + + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while getting payment configurations",e); + } + + } + + @Override + public ReadableConfiguration configuration(String module, MerchantStore store) { + + try { + + ReadableConfiguration config = null; + List methods = paymentService.getAcceptedPaymentMethods(store); + Optional configuration = + methods.stream() + .filter(m -> module.equals(m.getModule().getCode())) + .map(m -> this.configuration(m.getInformations(), store)) + .findFirst(); + + if(configuration.isPresent()) { + config = configuration.get(); + } + + return config; + + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while getting payment configuration [" + module + "]",e); + } + + } + + @Override + public void saveConfiguration(PersistableConfiguration configuration, MerchantStore store) { + // TODO Auto-generated method stub + + } + + @Override + public void deleteConfiguration(String module, MerchantStore store) { + // TODO Auto-generated method stub + + } + + + private ReadableConfiguration configuration(IntegrationConfiguration source, MerchantStore store) { + + ReadableConfiguration config = new ReadableConfiguration(); + config.setActive(source.isActive()); + config.setCode(source.getModuleCode()); + config.setKeys(source.getIntegrationKeys()); + config.setIntegrationOptions(source.getIntegrationOptions()); + + return config; + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductCommonFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductCommonFacadeImpl.java new file mode 100644 index 0000000000..cd3d30248b --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductCommonFacadeImpl.java @@ -0,0 +1,477 @@ +package com.salesmanager.shop.store.facade.product; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.review.ProductReviewService; +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.model.catalog.category.Category; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.catalog.product.review.ProductReview; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.catalog.product.PersistableProductMapper; +import com.salesmanager.shop.model.catalog.product.LightPersistableProduct; +import com.salesmanager.shop.model.catalog.product.PersistableProductReview; +import com.salesmanager.shop.model.catalog.product.ProductPriceEntity; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.model.catalog.product.ReadableProductReview; +import com.salesmanager.shop.model.catalog.product.product.PersistableProduct; +import com.salesmanager.shop.model.catalog.product.product.ProductSpecification; +import com.salesmanager.shop.populator.catalog.PersistableProductReviewPopulator; +import com.salesmanager.shop.populator.catalog.ReadableProductPopulator; +import com.salesmanager.shop.populator.catalog.ReadableProductReviewPopulator; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.store.api.exception.OperationNotAllowedException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.product.facade.ProductCommonFacade; +import com.salesmanager.shop.utils.DateUtil; +import com.salesmanager.shop.utils.ImageFilePath; + + +/** + * Version 1 Product management + * Version 2 Recommends using productVariant + * @author carlsamson + * + */ +@Service("productCommonFacade") +public class ProductCommonFacadeImpl implements ProductCommonFacade { + + + @Inject + private LanguageService languageService; + + @Inject + private ProductService productService; + + @Inject + private PricingService pricingService; + + @Inject + private CustomerService customerService; + + @Inject + private ProductReviewService productReviewService; + + @Autowired + private PersistableProductMapper persistableProductMapper; + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + @Override + public Long saveProduct(MerchantStore store, PersistableProduct product, Language language) { + + String manufacturer = Manufacturer.DEFAULT_MANUFACTURER; + if (product.getProductSpecifications() != null) { + manufacturer = product.getProductSpecifications().getManufacturer(); + } else { + ProductSpecification specifications = new ProductSpecification(); + specifications.setManufacturer(manufacturer); + } + + Product target = null; + if (product.getId() != null && product.getId().longValue() > 0) { + target = productService.getById(product.getId()); + } else { + target = new Product(); + } + + try { + + target = persistableProductMapper.merge(product, target, store, language); + target = productService.saveProduct(target); + + + return target.getId(); + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + + } + + public void updateProduct(MerchantStore store, PersistableProduct product, Language language) { + + Validate.notNull(product, "Product must not be null"); + Validate.notNull(product.getId(), "Product id must not be null"); + + // get original product + Product productModel = productService.getById(product.getId()); + + + } + + @Override + public ReadableProduct getProduct(MerchantStore store, Long id, Language language) { + + Product product = productService.findOne(id, store); + if (product == null) { + throw new ResourceNotFoundException("Product [" + id + "] not found"); + } + + if (product.getMerchantStore().getId() != store.getId()) { + throw new ResourceNotFoundException("Product [" + id + "] not found for store [" + store.getId() + "]"); + } + + ReadableProduct readableProduct = new ReadableProduct(); + ReadableProductPopulator populator = new ReadableProductPopulator(); + populator.setPricingService(pricingService); + populator.setimageUtils(imageUtils); + try { + readableProduct = populator.populate(product, readableProduct, store, language); + } catch (ConversionException e) { + throw new ConversionRuntimeException("Error converting product [" + id + "]",e); + } + + return readableProduct; + } + + + @Override + public ReadableProduct updateProductPrice(ReadableProduct product, ProductPriceEntity price, Language language) + throws Exception { + + Product persistable = productService.getById(product.getId()); + + if (persistable == null) { + throw new Exception("product is null for id " + product.getId()); + } + + java.util.Set availabilities = persistable.getAvailabilities(); + for (ProductAvailability availability : availabilities) { + ProductPrice productPrice = availability.defaultPrice(); + productPrice.setProductPriceAmount(price.getPrice()); + if (price.isDiscounted()) { + productPrice.setProductPriceSpecialAmount(price.getDiscountedPrice()); + if (!StringUtils.isBlank(price.getDiscountStartDate())) { + Date startDate = DateUtil.getDate(price.getDiscountStartDate()); + productPrice.setProductPriceSpecialStartDate(startDate); + } + if (!StringUtils.isBlank(price.getDiscountEndDate())) { + Date endDate = DateUtil.getDate(price.getDiscountEndDate()); + productPrice.setProductPriceSpecialEndDate(endDate); + } + } + + } + + productService.update(persistable); + + ReadableProduct readableProduct = new ReadableProduct(); + + ReadableProductPopulator populator = new ReadableProductPopulator(); + + populator.setPricingService(pricingService); + populator.setimageUtils(imageUtils); + populator.populate(persistable, readableProduct, persistable.getMerchantStore(), language); + + return readableProduct; + } + + @Override + public ReadableProduct updateProductQuantity(ReadableProduct product, int quantity, Language language) + throws Exception { + Product persistable = productService.getById(product.getId()); + + if (persistable == null) { + throw new Exception("product is null for id " + product.getId()); + } + + java.util.Set availabilities = persistable.getAvailabilities(); + for (ProductAvailability availability : availabilities) { + availability.setProductQuantity(quantity); + } + + productService.saveProduct(persistable); + + ReadableProduct readableProduct = new ReadableProduct(); + + ReadableProductPopulator populator = new ReadableProductPopulator(); + + populator.setPricingService(pricingService); + populator.setimageUtils(imageUtils); + populator.populate(persistable, readableProduct, persistable.getMerchantStore(), language); + + return readableProduct; + } + + @Override + public void deleteProduct(Product product) throws Exception { + productService.delete(product); + + } + + + @Override + public ReadableProduct addProductToCategory(Category category, Product product, Language language) { + + Validate.notNull(category, "Category cannot be null"); + Validate.notNull(product, "Product cannot be null"); + + // not alloweed if category already attached + List assigned = product.getCategories().stream() + .filter(cat -> cat.getId().longValue() == category.getId().longValue()).collect(Collectors.toList()); + + if (assigned.size() > 0) { + throw new OperationNotAllowedException("Category with id [" + category.getId() + + "] already attached to product [" + product.getId() + "]"); + } + + product.getCategories().add(category); + ReadableProduct readableProduct = new ReadableProduct(); + + try { + + productService.saveProduct(product); + + ReadableProductPopulator populator = new ReadableProductPopulator(); + + populator.setPricingService(pricingService); + populator.setimageUtils(imageUtils); + populator.populate(product, readableProduct, product.getMerchantStore(), language); + + } catch(Exception e) { + throw new RuntimeException("Exception when adding product [" + product.getId() + "] to category [" + category.getId() + "]",e); + } + + return readableProduct; + + } + + @Override + public ReadableProduct removeProductFromCategory(Category category, Product product, Language language) + throws Exception { + + Validate.notNull(category, "Category cannot be null"); + Validate.notNull(product, "Product cannot be null"); + + product.getCategories().remove(category); + productService.saveProduct(product); + + ReadableProduct readableProduct = new ReadableProduct(); + + ReadableProductPopulator populator = new ReadableProductPopulator(); + + populator.setPricingService(pricingService); + populator.setimageUtils(imageUtils); + populator.populate(product, readableProduct, product.getMerchantStore(), language); + + return readableProduct; + } + + @Override + public ReadableProduct getProductByCode(MerchantStore store, String uniqueCode, Language language) + throws Exception { + + Product product = productService.getBySku(uniqueCode, store, language); + + ReadableProduct readableProduct = new ReadableProduct(); + + ReadableProductPopulator populator = new ReadableProductPopulator(); + + populator.setPricingService(pricingService); + populator.setimageUtils(imageUtils); + populator.populate(product, readableProduct, product.getMerchantStore(), language); + + return readableProduct; + } + + @Override + public void saveOrUpdateReview(PersistableProductReview review, MerchantStore store, Language language) + throws Exception { + PersistableProductReviewPopulator populator = new PersistableProductReviewPopulator(); + populator.setLanguageService(languageService); + populator.setCustomerService(customerService); + populator.setProductService(productService); + + com.salesmanager.core.model.catalog.product.review.ProductReview rev = new com.salesmanager.core.model.catalog.product.review.ProductReview(); + populator.populate(review, rev, store, language); + + if (review.getId() == null) { + productReviewService.create(rev); + } else { + productReviewService.update(rev); + } + + review.setId(rev.getId()); + + } + + @Override + public void deleteReview(ProductReview review, MerchantStore store, Language language) throws Exception { + productReviewService.delete(review); + + } + + @Override + public List getProductReviews(Product product, MerchantStore store, Language language) + throws Exception { + + List reviews = productReviewService.getByProduct(product); + + ReadableProductReviewPopulator populator = new ReadableProductReviewPopulator(); + + List productReviews = new ArrayList(); + + for (ProductReview review : reviews) { + ReadableProductReview readableReview = new ReadableProductReview(); + populator.populate(review, readableReview, store, language); + productReviews.add(readableReview); + } + + return productReviews; + } + + + @Override + public void update(Long productId, LightPersistableProduct product, MerchantStore merchant, Language language) { + // Get product + Product modified = productService.findOne(productId, merchant); + + // Update product with minimal set + modified.setAvailable(product.isAvailable()); + + for (ProductAvailability availability : modified.getAvailabilities()) { + availability.setProductQuantity(product.getQuantity()); + if (!StringUtils.isBlank(product.getPrice())) { + // set default price + for (ProductPrice price : availability.getPrices()) { + if (price.isDefaultPrice()) { + try { + price.setProductPriceAmount(pricingService.getAmount(product.getPrice())); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Invalid product price format"); + } + } + } + } + } + + try { + productService.save(modified); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Cannot update product ", e); + } + + } + + @Override + public boolean exists(String sku, MerchantStore store) { + + return productService.exists(sku, store); + } + + + @Override + public void deleteProduct(Long id, MerchantStore store) { + + Validate.notNull(id, "Product id cannot be null"); + Validate.notNull(store, "store cannot be null"); + + Product p = productService.getById(id); + + if (p == null) { + throw new ResourceNotFoundException("Product with id [" + id + " not found"); + } + + if (p.getMerchantStore().getId().intValue() != store.getId().intValue()) { + throw new ResourceNotFoundException( + "Product with id [" + id + " not found for store [" + store.getCode() + "]"); + } + + try { + productService.delete(p); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while deleting ptoduct with id [" + id + "]", e); + } + + } + + + + @Override + public Product getProduct(Long id, MerchantStore store) { + return productService.findOne(id, store); + } + + @Override + public void update(String sku, LightPersistableProduct product, MerchantStore merchant, Language language) { + // Get product + Product modified = null; + try { + modified = productService.getBySku(sku, merchant, language); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + + ProductVariant instance = modified.getVariants().stream() + .filter(inst -> sku.equals(inst.getSku())) + .findAny() + .orElse(null); + + if(instance!=null) { + instance.setAvailable(product.isAvailable()); + + for (ProductAvailability availability : instance.getAvailabilities()) { + this.setAvailability(availability, product); + } + } else { + // Update product with minimal set + modified.setAvailable(product.isAvailable()); + + for (ProductAvailability availability : modified.getAvailabilities()) { + this.setAvailability(availability, product); + } + } + + try { + productService.saveProduct(modified); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Cannot update product ", e); + } + + } + + /** + * edit availability + */ + private void setAvailability(ProductAvailability availability, LightPersistableProduct product) { + availability.setProductQuantity(product.getQuantity()); + if (!StringUtils.isBlank(product.getPrice())) { + // set default price + for (ProductPrice price : availability.getPrices()) { + if (price.isDefaultPrice()) { + try { + price.setProductPriceAmount(pricingService.getAmount(product.getPrice())); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Invalid product price format"); + } + } + } + } + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductDefinitionFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductDefinitionFacadeImpl.java new file mode 100644 index 0000000000..9e2eecbd16 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductDefinitionFacadeImpl.java @@ -0,0 +1,105 @@ +package com.salesmanager.shop.store.facade.product; + +import java.util.Optional; + +import javax.inject.Inject; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.catalog.product.PersistableProductDefinitionMapper; +import com.salesmanager.shop.mapper.catalog.product.ReadableProductDefinitionMapper; +import com.salesmanager.shop.model.catalog.product.product.definition.PersistableProductDefinition; +import com.salesmanager.shop.model.catalog.product.product.definition.ReadableProductDefinition; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.product.facade.ProductDefinitionFacade; +import com.salesmanager.shop.store.controller.product.facade.ProductVariantFacade; +import com.salesmanager.shop.utils.ImageFilePath; + +@Service("productDefinitionFacade") +@Profile({ "default", "cloud", "gcp", "aws", "mysql", "local" }) +public class ProductDefinitionFacadeImpl implements ProductDefinitionFacade { + + + + @Inject + private ProductService productService; + + + @Autowired + private PersistableProductDefinitionMapper persistableProductDefinitionMapper; + + @Autowired + private ReadableProductDefinitionMapper readableProductDefinitionMapper; + + @Autowired + private ProductVariantFacade productVariantFacade; + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + @Override + public Long saveProductDefinition(MerchantStore store, PersistableProductDefinition product, Language language) { + + + Product target = null; + if (product.getId() != null && product.getId().longValue() > 0) { + Optional p = productService.retrieveById(product.getId(), store); + if(p.isEmpty()) { + throw new ResourceNotFoundException("Product with id [" + product.getId() + "] not found for store [" + store.getCode() + "]"); + } + target = p.get(); + } else { + target = new Product(); + } + + try { + target = persistableProductDefinitionMapper.merge(product, target, store, language); + + productService.saveProduct(target); + product.setId(target.getId()); + + + return target.getId(); + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + + } + + @Override + public void update(Long id, PersistableProductDefinition product, MerchantStore merchant, + Language language) { + product.setId(id); + this.saveProductDefinition(merchant, product, language); + } + + @Override + public ReadableProductDefinition getProduct(MerchantStore store, Long id, Language language) { + Product product = productService.findOne(id, store); + return readableProductDefinitionMapper.convert(product, store, language); + } + + @Override + public ReadableProductDefinition getProductBySku(MerchantStore store, String uniqueCode, Language language) { + + Product product = null; + try { + product = productService.getBySku(uniqueCode, store, language); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + return readableProductDefinitionMapper.convert(product, store, language); + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductFacadeImpl.java new file mode 100755 index 0000000000..ee0ee4bf04 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductFacadeImpl.java @@ -0,0 +1,273 @@ +package com.salesmanager.shop.store.facade.product; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Profile; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.category.CategoryService; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService; +import com.salesmanager.core.business.services.catalog.product.relationship.ProductRelationshipService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.ProductCriteria; +import com.salesmanager.core.model.catalog.product.relationship.ProductRelationship; +import com.salesmanager.core.model.catalog.product.relationship.ProductRelationshipType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.model.catalog.product.ReadableProductList; +import com.salesmanager.shop.model.catalog.product.product.PersistableProduct; +import com.salesmanager.shop.populator.catalog.ReadableProductPopulator; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.product.facade.ProductFacade; +import com.salesmanager.shop.utils.ImageFilePath; +import com.salesmanager.shop.utils.LocaleUtils; + +@Service("productFacade") +@Profile({ "default", "cloud", "gcp", "aws", "mysql" , "local" }) +public class ProductFacadeImpl implements ProductFacade { + + @Inject + private CategoryService categoryService; + + @Inject + private ProductAttributeService productAttributeService; + + @Inject + private ProductService productService; + + @Inject + private PricingService pricingService; + + @Inject + private ProductRelationshipService productRelationshipService; + + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + public void updateProduct(MerchantStore store, PersistableProduct product, Language language) { + + Validate.notNull(product, "Product must not be null"); + Validate.notNull(product.getId(), "Product id must not be null"); + + // get original product + productService.getById(product.getId()); + + } + + @Override + public ReadableProduct getProduct(MerchantStore store, String sku, Language language) throws Exception { + + Product product = productService.getBySku(sku, store, language); + + if (product == null) { + return null; + } + + ReadableProduct readableProduct = new ReadableProduct(); + + ReadableProductPopulator populator = new ReadableProductPopulator(); + + populator.setPricingService(pricingService); + populator.setimageUtils(imageUtils); + populator.populate(product, readableProduct, store, language); + + return readableProduct; + } + + @Override + public ReadableProductList getProductListsByCriterias(MerchantStore store, Language language, + ProductCriteria criterias) throws Exception { + + Validate.notNull(criterias, "ProductCriteria must be set for this product"); + + /** This is for category **/ + if (CollectionUtils.isNotEmpty(criterias.getCategoryIds())) { + + if (criterias.getCategoryIds().size() == 1) { + + com.salesmanager.core.model.catalog.category.Category category = categoryService + .getById(criterias.getCategoryIds().get(0)); + + if (category != null) { + String lineage = new StringBuilder().append(category.getLineage()) + .toString(); + + List categories = categoryService + .getListByLineage(store, lineage); + + List ids = new ArrayList(); + if (categories != null && categories.size() > 0) { + for (com.salesmanager.core.model.catalog.category.Category c : categories) { + ids.add(c.getId()); + } + } + ids.add(category.getId()); + criterias.setCategoryIds(ids); + } + } + } + + + Page modelProductList = productService.listByStore(store, language, criterias, criterias.getStartPage(), criterias.getMaxCount()); + + List products = modelProductList.getContent(); + + List prds = products.stream().sorted(Comparator.comparing(Product::getSortOrder)).collect(Collectors.toList()); + products = prds; + + ReadableProductPopulator populator = new ReadableProductPopulator(); + populator.setPricingService(pricingService); + populator.setimageUtils(imageUtils); + + ReadableProductList productList = new ReadableProductList(); + for (Product product : products) { + + // create new proxy product + ReadableProduct readProduct = populator.populate(product, new ReadableProduct(), store, language); + productList.getProducts().add(readProduct); + + } + + // productList.setTotalPages(products.getTotalCount()); + productList.setRecordsTotal(modelProductList.getTotalElements()); + productList.setNumber(productList.getProducts().size()); + + productList.setTotalPages(modelProductList.getTotalPages()); + + return productList; + } + + @Override + public ReadableProduct getProductByCode(MerchantStore store, String uniqueCode, Language language) { + + Product product = null; + try { + product = productService.getBySku(uniqueCode, store, language); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + + ReadableProduct readableProduct = new ReadableProduct(); + + ReadableProductPopulator populator = new ReadableProductPopulator(); + + populator.setPricingService(pricingService); + populator.setimageUtils(imageUtils); + try { + populator.populate(product, readableProduct, product.getMerchantStore(), language); + } catch (ConversionException e) { + throw new ConversionRuntimeException("Product with code [" + uniqueCode + "] cannot be converted", e); + } + + return readableProduct; + } + + @Override + public List relatedItems(MerchantStore store, Product product, Language language) + throws Exception { + ReadableProductPopulator populator = new ReadableProductPopulator(); + populator.setPricingService(pricingService); + populator.setimageUtils(imageUtils); + + List relatedItems = productRelationshipService.getByType(store, product, + ProductRelationshipType.RELATED_ITEM); + if (relatedItems != null && relatedItems.size() > 0) { + List items = new ArrayList(); + for (ProductRelationship relationship : relatedItems) { + Product relatedProduct = relationship.getRelatedProduct(); + ReadableProduct proxyProduct = populator.populate(relatedProduct, new ReadableProduct(), store, + language); + items.add(proxyProduct); + } + return items; + } + return null; + } + + + + @Override + public ReadableProduct getProductBySeUrl(MerchantStore store, String friendlyUrl, Language language) throws Exception { + + Product product = productService.getBySeUrl(store, friendlyUrl, LocaleUtils.getLocale(language)); + + if (product == null) { + return null; + } + + ReadableProduct readableProduct = new ReadableProduct(); + + ReadableProductPopulator populator = new ReadableProductPopulator(); + + populator.setPricingService(pricingService); + populator.setimageUtils(imageUtils); + populator.populate(product, readableProduct, store, language); + + return readableProduct; + } + + /** + @Override + public ReadableProductPrice getProductPrice(Long id, ProductPriceRequest priceRequest, MerchantStore store, Language language) { + Validate.notNull(id, "Product id cannot be null"); + Validate.notNull(priceRequest, "Product price request cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + + try { + Product model = productService.findOne(id, store); + + //TODO check if null + List attrinutesIds = priceRequest.getOptions().stream().map(p -> p.getId()).collect(Collectors.toList()); + + List attributes = productAttributeService.getByAttributeIds(store, model, attrinutesIds); + + for(ProductAttribute attribute : attributes) { + if(attribute.getProduct().getId().longValue()!= id.longValue()) { + //throw unauthorized + throw new OperationNotAllowedException("Attribute with id [" + attribute.getId() + "] is not attached to product id [" + id + "]"); + } + } + + FinalPrice price; + + price = pricingService.calculateProductPrice(model, attributes); + ReadableProductPrice readablePrice = new ReadableProductPrice(); + ReadableFinalPricePopulator populator = new ReadableFinalPricePopulator(); + populator.setPricingService(pricingService); + + + return populator.populate(price, readablePrice, store, language); + + } catch (Exception e) { + throw new ServiceRuntimeException("An error occured while getting product price",e); + } + + } + **/ + + @Override + public Product getProduct(Long id, MerchantStore store) { + return productService.findOne(id, store); + } + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductFacadeV2Impl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductFacadeV2Impl.java new file mode 100644 index 0000000000..fad03cc92e --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductFacadeV2Impl.java @@ -0,0 +1,289 @@ +package com.salesmanager.shop.store.facade.product; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Profile; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.category.CategoryService; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService; +import com.salesmanager.core.business.services.catalog.product.availability.ProductAvailabilityService; +import com.salesmanager.core.business.services.catalog.product.relationship.ProductRelationshipService; +import com.salesmanager.core.business.services.catalog.product.variant.ProductVariantService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.ProductCriteria; +import com.salesmanager.core.model.catalog.product.relationship.ProductRelationship; +import com.salesmanager.core.model.catalog.product.relationship.ProductRelationshipType; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.catalog.product.ReadableProductMapper; +import com.salesmanager.shop.mapper.catalog.product.ReadableProductVariantMapper; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.model.catalog.product.ReadableProductList; +import com.salesmanager.shop.model.catalog.product.product.variant.ReadableProductVariant; +import com.salesmanager.shop.populator.catalog.ReadableProductPopulator; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.product.facade.ProductFacade; +import com.salesmanager.shop.utils.ImageFilePath; +import com.salesmanager.shop.utils.LocaleUtils; + + +@Service("productFacadeV2") +@Profile({ "default", "cloud", "gcp", "aws", "mysql" , "local" }) +public class ProductFacadeV2Impl implements ProductFacade { + + + @Autowired + private ProductService productService; + + @Inject + private CategoryService categoryService; + + @Inject + private ProductRelationshipService productRelationshipService; + + @Autowired + private ReadableProductMapper readableProductMapper; + + @Autowired + private ProductVariantService productVariantService; + + @Autowired + private ReadableProductVariantMapper readableProductVariantMapper; + + @Autowired + private ProductAvailabilityService productAvailabilityService; + + @Autowired + private ProductAttributeService productAttributeService; + + @Inject + private PricingService pricingService; + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + + @Override + public Product getProduct(Long id, MerchantStore store) { + //same as v1 + return productService.findOne(id, store); + } + + @Override + public ReadableProduct getProductByCode(MerchantStore store, String sku, Language language) { + + + Product product = null; + try { + product = productService.getBySku(sku, store, language); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + + if (product == null) { + throw new ResourceNotFoundException("Product [" + sku + "] not found for merchant [" + store.getCode() + "]"); + } + + if (product.getMerchantStore().getId() != store.getId()) { + throw new ResourceNotFoundException("Product [" + sku + "] not found for merchant [" + store.getCode() + "]"); + } + + + ReadableProduct readableProduct = readableProductMapper.convert(product, store, language); + + return readableProduct; + + } + + private ReadableProductVariant productVariant(ProductVariant instance, MerchantStore store, Language language) { + + return readableProductVariantMapper.convert(instance, store, language); + + } + + @Override + public ReadableProduct getProduct(MerchantStore store, String sku, Language language) throws Exception { + return this.getProductByCode(store, sku, language); + } + + @Override + public ReadableProduct getProductBySeUrl(MerchantStore store, String friendlyUrl, Language language) + throws Exception { + + Product product = productService.getBySeUrl(store, friendlyUrl, LocaleUtils.getLocale(language)); + + if (product == null) { + throw new ResourceNotFoundException("Product [" + friendlyUrl + "] not found for merchant [" + store.getCode() + "]"); + } + + ReadableProduct readableProduct = readableProductMapper.convert(product, store, language); + + //get all instances for this product group by option + //limit to 15 searches + List instances = productVariantService.getByProductId(store, product, language); + + //the above get all possible images + List readableInstances = instances.stream().map(p -> this.productVariant(p, store, language)).collect(Collectors.toList()); + readableProduct.setVariants(readableInstances); + + return readableProduct; + + } + + /** + * Filters on otion, optionValues and other criterias + */ + + @Override + public ReadableProductList getProductListsByCriterias(MerchantStore store, Language language, + ProductCriteria criterias) throws Exception { + Validate.notNull(criterias, "ProductCriteria must be set for this product"); + + /** This is for category **/ + if (CollectionUtils.isNotEmpty(criterias.getCategoryIds())) { + + if (criterias.getCategoryIds().size() == 1) { + + com.salesmanager.core.model.catalog.category.Category category = categoryService + .getById(criterias.getCategoryIds().get(0)); + + if (category != null) { + String lineage = new StringBuilder().append(category.getLineage()) + .toString(); + + List categories = categoryService + .getListByLineage(store, lineage); + + List ids = new ArrayList(); + if (categories != null && categories.size() > 0) { + for (com.salesmanager.core.model.catalog.category.Category c : categories) { + ids.add(c.getId()); + } + } + ids.add(category.getId()); + criterias.setCategoryIds(ids); + } + } + } + + + Page modelProductList = productService.listByStore(store, language, criterias, criterias.getStartPage(), criterias.getMaxCount()); + + List products = modelProductList.getContent(); + ReadableProductList productList = new ReadableProductList(); + + + /** + * ReadableProductMapper + */ + + List readableProducts = products.stream().map(p -> readableProductMapper.convert(p, store, language)) + .sorted(Comparator.comparing(ReadableProduct::getSortOrder)).collect(Collectors.toList()); + + + productList.setRecordsTotal(modelProductList.getTotalElements()); + productList.setNumber(modelProductList.getNumberOfElements()); + productList.setProducts(readableProducts); + productList.setTotalPages(modelProductList.getTotalPages()); + + return productList; + } + + @Override + public List relatedItems(MerchantStore store, Product product, Language language) + throws Exception { + //same as v1 + ReadableProductPopulator populator = new ReadableProductPopulator(); + populator.setPricingService(pricingService); + populator.setimageUtils(imageUtils); + + List relatedItems = productRelationshipService.getByType(store, product, + ProductRelationshipType.RELATED_ITEM); + if (relatedItems != null && relatedItems.size() > 0) { + List items = new ArrayList(); + for (ProductRelationship relationship : relatedItems) { + Product relatedProduct = relationship.getRelatedProduct(); + ReadableProduct proxyProduct = populator.populate(relatedProduct, new ReadableProduct(), store, + language); + items.add(proxyProduct); + } + return items; + } + return null; + } + + + /** + @Override + public ReadableProductPrice getProductPrice(Long id, ProductPriceRequest priceRequest, MerchantStore store, + Language language) { + + + Validate.notNull(id, "Product id cannot be null"); + Validate.notNull(priceRequest, "Product price request cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + + try { + Product model = productService.findOne(id, store); + + List attributes = null; + + if(!CollectionUtils.isEmpty(priceRequest.getOptions())) { + List attrinutesIds = priceRequest.getOptions().stream().map(p -> p.getId()).collect(Collectors.toList()); + + attributes = productAttributeService.getByAttributeIds(store, model, attrinutesIds); + + for(ProductAttribute attribute : attributes) { + if(attribute.getProduct().getId().longValue()!= id.longValue()) { + //throw unauthorized + throw new OperationNotAllowedException("Attribute with id [" + attribute.getId() + "] is not attached to product id [" + id + "]"); + } + } + } + + if(!StringUtils.isBlank(priceRequest.getSku())) { + //change default availability with sku (instance availability) + List availabilityList = productAvailabilityService.getBySku(priceRequest.getSku(), store); + if(CollectionUtils.isNotEmpty(availabilityList)) { + model.setAvailabilities(new HashSet(availabilityList)); + } + } + + FinalPrice price; + + //attributes can be null; + price = pricingService.calculateProductPrice(model, attributes); + ReadableProductPrice readablePrice = new ReadableProductPrice(); + ReadableFinalPricePopulator populator = new ReadableFinalPricePopulator(); + populator.setPricingService(pricingService); + + + return populator.populate(price, readablePrice, store, language); + + } catch (Exception e) { + throw new ServiceRuntimeException("An error occured while getting product price",e); + } + + + } + **/ + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductInventoryFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductInventoryFacadeImpl.java new file mode 100644 index 0000000000..a8f2db8405 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductInventoryFacadeImpl.java @@ -0,0 +1,265 @@ +package com.salesmanager.shop.store.facade.product; + +import static com.salesmanager.shop.util.ReadableEntityUtil.createReadableList; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.availability.ProductAvailabilityService; +import com.salesmanager.core.business.services.catalog.product.variant.ProductVariantService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.inventory.PersistableInventoryMapper; +import com.salesmanager.shop.mapper.inventory.ReadableInventoryMapper; +import com.salesmanager.shop.model.catalog.product.inventory.PersistableInventory; +import com.salesmanager.shop.model.catalog.product.inventory.ReadableInventory; +import com.salesmanager.shop.model.entity.ReadableEntityList; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.product.facade.ProductInventoryFacade; + +@Service("productInventoryFacade") +@Profile({ "default", "cloud", "gcp", "aws", "mysql", "local" }) +public class ProductInventoryFacadeImpl implements ProductInventoryFacade { + + @Autowired + private ProductAvailabilityService productAvailabilityService; + + @Autowired + private ProductService productService; + + @Autowired + private ProductVariantService productVariantService; + + @Autowired + private ReadableInventoryMapper readableInventoryMapper; + + @Autowired + private PersistableInventoryMapper productInventoryMapper; + + + + private void validateProductHasSameStore(MerchantStore store, Product product) { + if (!product.getMerchantStore().getId().equals(store.getId())) { + throw new ResourceNotFoundException("Product with id [" + product.getId() + "] not found for store id [" + + store.getInvoiceTemplate() + "]"); + } + } + + @Override + public void delete(Long productId, Long inventoryId, MerchantStore store) { + Optional availability = productAvailabilityService.getById(inventoryId, store); + try { + if (availability.isPresent()) { + if(availability.get().getProduct().getId() == productId) { + productAvailabilityService.delete(availability.get()); + } else { + throw new ResourceNotFoundException("Product with id [" + productId + "] and inventory id [" + inventoryId + "] not found for store id [" + store.getId() + "]"); + } + } else { + throw new ResourceNotFoundException("Product with id [" + productId + "] and inventory id [" + inventoryId + "] not found for store id [" + store.getId() + "]"); + } + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while deleting inventory", e); + } + } + + /* + * @Override public ReadableInventory get(Long inventoryId, MerchantStore store, + * Language language) { ProductAvailability availability = + * getAvailabilityById(store, inventoryId); return + * readableInventoryMapper.convert(availability, store, language); } + */ + + + //public ReadableInventory get(String child, Language language) { + /* + * Product product = getProductById(productId); MerchantStore store = + * getMerchantStore(child); + * + * if (isStoreParentNotExist(store) || + * store.getParent().getId().equals(product.getMerchantStore().getId())) { throw + * new ResourceNotFoundException( "MerchantStore [" + child + + * "] is not a store of retailer [" + store.getCode() + "]"); } + * + * ProductAvailability availability = + * productAvailabilityService.getByStore(product, store) .orElseThrow(() -> new + * ResourceNotFoundException("Inventory with not found")); + * + * return this.readableInventory(availability, store, language); + */ + //} + + /** + private boolean isStoreParentNotExist(MerchantStore store) { + return Objects.isNull(store.getParent()); + } + + + private MerchantStore getMerchantStore(String child) { + try { + return Optional.ofNullable(merchantStoreService.getByCode(child)) + .orElseThrow(() -> new ResourceNotFoundException("MerchantStore [" + child + "] not found")); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while getting inventory", e); + } + } + + private ReadableInventory readableInventory(ProductAvailability availability, MerchantStore store, Language language) { + return readableInventoryMapper.convert(availability, store, language); + } + **/ + + + private Product getProductById(Long productId, MerchantStore store) { + return productService + .retrieveById(productId, store) + .orElseThrow(() -> new ResourceNotFoundException("Product with id [" + productId + "] not found")); + } + + private ProductVariant getProductByInstance(Long instanceId, MerchantStore store) { + return productVariantService.getById(instanceId, store).orElseThrow(() -> new ResourceNotFoundException("Product with instance [" + instanceId + "] not found")); + + } + + @Override + public ReadableInventory add(PersistableInventory inventory, MerchantStore store, + Language language) { + Validate.notNull(store, "MerchantStore cannot be null"); + ProductAvailability availability = getProductAvailabilityToSave(inventory, store); + + //add inventory to the product + + saveOrUpdate(availability); + return readableInventoryMapper.convert(availability, store, language); + } + + private void saveOrUpdate(ProductAvailability availability) { + try { + productAvailabilityService.saveOrUpdate(availability); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Cannot create Inventory", e); + } + } + + private ProductAvailability getProductAvailabilityToSave(PersistableInventory inventory, MerchantStore store) { + + return productInventoryMapper.convert(inventory, store, store.getDefaultLanguage()); + + } + + @Override + public ReadableInventory get(Long inventoryId, MerchantStore store, Language language) { + + + ProductAvailability availability = productAvailabilityService.getById(inventoryId, store) + .orElseThrow(() -> new ResourceNotFoundException("Inventory with id [" + inventoryId + "] not found")); + return readableInventoryMapper.convert(availability, store, language); + } + + @Override + public void update(PersistableInventory inventory, MerchantStore store, Language language) { + + Validate.notNull(inventory, "Inventory cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + + Set originAvailability = null; + Product product = null; + + if(inventory.getProductId()!=null && inventory.getProductId().longValue()>0) { + product = this.getProductById(inventory.getProductId(), store); + originAvailability = product.getAvailabilities(); + } else { + if(inventory.getVariant() != null && inventory.getId().longValue() > 0) { + ProductVariant instance = this.getProductByInstance(inventory.getVariant(), store); + originAvailability = instance.getAvailabilities(); + product = instance.getProduct(); + } + } + + ProductAvailability avail = originAvailability.stream() + .filter(a -> a.getId().longValue() == inventory.getId()) + .findAny() + .orElse(null); + + if (avail == null) { + throw new ResourceNotFoundException( + "Inventory with id [" + inventory.getId() + "] not found"); + } + + + inventory.setProductId(product.getId()); + + avail = productInventoryMapper.merge(inventory, avail, store, language); + avail.setProduct(product); + avail.setMerchantStore(store); + saveOrUpdate(avail); + } + + + + @Override + public ReadableEntityList get(String sku, MerchantStore store, Language language, int page, int count) { + Validate.notNull(sku, "Product sku cannot be null"); + Validate.notNull(store, "MerchantStore code cannot be null"); + Validate.notNull(language, "Language cannot be null"); + + Page availabilities = productAvailabilityService.getBySku(sku, page, count); + + /** + * br -> if availabilities is null, it may be bcz a variant is a decorated product with no specific inventory. + * in this case it should display the parent product inventory + * + */ + + if(availabilities.isEmpty()) { + //get parent product + try { + Product singleProduct = productService.getBySku(sku, store); + if(singleProduct!=null) { + availabilities = new PageImpl(new ArrayList(singleProduct.getAvailabilities())); + } + } catch (ServiceException e) { + throw new ServiceRuntimeException("An error occured while getting product with sku " + sku,e); + } + } + + List returnList = availabilities.getContent().stream().map(i -> this.readableInventoryMapper.convert(i, store, language)) + .collect(Collectors.toList()); + + return createReadableList(availabilities, returnList); + } + + @Override + public ReadableEntityList get(Long productId, MerchantStore store, Language language, int page, int count) { + + Validate.notNull(productId, "Product id cannot be null"); + Validate.notNull(store, "MerchantStore code cannot be null"); + + Page availabilities = productAvailabilityService.listByProduct(productId, store, page, count); + + List returnList = availabilities.getContent().stream().map(i -> this.readableInventoryMapper.convert(i, store, language)) + .collect(Collectors.toList()); + + return createReadableList(availabilities, returnList); + + } + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductOptionFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductOptionFacadeImpl.java new file mode 100644 index 0000000000..3ce0bd87d0 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductOptionFacadeImpl.java @@ -0,0 +1,513 @@ +package com.salesmanager.shop.store.facade.product; + +import java.io.InputStream; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.NotImplementedException; +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductAttributeService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductOptionService; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductOptionValueService; +import com.salesmanager.core.business.services.content.ContentService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.attribute.ProductAttribute; +import com.salesmanager.core.model.catalog.product.attribute.ProductOption; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionValue; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.InputContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.catalog.PersistableProductAttributeMapper; +import com.salesmanager.shop.mapper.catalog.PersistableProductOptionMapper; +import com.salesmanager.shop.mapper.catalog.PersistableProductOptionValueMapper; +import com.salesmanager.shop.mapper.catalog.ReadableProductAttributeMapper; +import com.salesmanager.shop.mapper.catalog.ReadableProductOptionMapper; +import com.salesmanager.shop.mapper.catalog.ReadableProductOptionValueMapper; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductAttribute; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductOptionValue; +import com.salesmanager.shop.model.catalog.product.attribute.api.PersistableProductOptionEntity; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductAttributeEntity; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductAttributeList; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionEntity; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionList; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionValue; +import com.salesmanager.shop.model.catalog.product.attribute.api.ReadableProductOptionValueList; +import com.salesmanager.shop.model.entity.CodeEntity; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.product.facade.ProductOptionFacade; + +@Service +public class ProductOptionFacadeImpl implements ProductOptionFacade { + + @Autowired + private ProductOptionService productOptionService; + + @Autowired + private ProductOptionValueService productOptionValueService; + + @Autowired + private ReadableProductOptionMapper readableMapper; + + @Autowired + private PersistableProductOptionMapper persistableeMapper; + + @Autowired + private PersistableProductOptionValueMapper persistableOptionValueMapper; + + @Autowired + private ReadableProductOptionValueMapper readableOptionValueMapper; + + @Autowired + private ContentService contentService; + + @Autowired + private ProductAttributeService productAttributeService; + + @Autowired + private PersistableProductAttributeMapper persistableProductAttributeMapper; + + @Autowired + private ReadableProductAttributeMapper readableProductAttributeMapper; + + @Autowired + private ProductService productService; + + @Override + public ReadableProductOptionEntity saveOption(PersistableProductOptionEntity option, MerchantStore store, + Language language) { + Validate.notNull(option, "ProductOption cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + + ProductOption optionModel = new ProductOption(); + if (option.getId() != null && option.getId().longValue() > 0) { + optionModel = productOptionService.getById(store, option.getId()); + if (optionModel == null) { + throw new ResourceNotFoundException( + "ProductOption not found for if [" + option.getId() + "] and store [" + store.getCode() + "]"); + } + } + + optionModel = persistableeMapper.merge(option, optionModel, store, language); + try { + productOptionService.saveOrUpdate(optionModel); + } catch (ServiceException e) { + throw new ServiceRuntimeException("An exception occured while saving ProductOption", e); + } + + optionModel = productOptionService.getById(store, optionModel.getId()); + ReadableProductOptionEntity readable = readableMapper.convert(optionModel, store, language); + return readable; + + } + + @Override + public void deleteOption(Long optionId, MerchantStore store) { + ProductOption optionModel = productOptionService.getById(store, optionId); + if (optionModel == null) { + throw new ResourceNotFoundException( + "ProductOption not found for [" + optionId + "] and store [" + store.getCode() + "]"); + } + try { + productOptionService.delete(optionModel); + } catch (ServiceException e) { + throw new ServiceRuntimeException("An exception occured while deleting ProductOption [" + optionId + "]", + e); + } + } + + @Override + public void deleteOptionValue(Long optionValueId, MerchantStore store) { + ProductOptionValue optionModel = productOptionValueService.getById(store, optionValueId); + if (optionModel == null) { + throw new ResourceNotFoundException( + "ProductOptionValue not found for [" + optionValueId + "] and store [" + store.getCode() + "]"); + } + try { + productOptionValueService.delete(optionModel); + } catch (ServiceException e) { + throw new ServiceRuntimeException( + "An exception occured while deleting ProductOptionValue [" + optionValueId + "]", e); + } + + } + + @Override + public ReadableProductOptionValueList optionValues(MerchantStore store, Language language, String name, int page, + int count) { + Validate.notNull(store, "MerchantStore should not be null"); + + Page options = productOptionValueService.getByMerchant(store, null, name, page, count); + ReadableProductOptionValueList valueList = new ReadableProductOptionValueList(); + valueList.setTotalPages(options.getTotalPages()); + valueList.setRecordsTotal(options.getTotalElements()); + valueList.setNumber(options.getNumber()); + + List values = options.getContent().stream() + .map(option -> readableOptionValueMapper.convert(option, store, null)).collect(Collectors.toList()); + + valueList.setOptionValues(values); + + return valueList; + } + + @Override + public ReadableProductOptionList options(MerchantStore store, Language language, String name, int page, int count) { + Validate.notNull(store, "MerchantStore should not be null"); + + Page options = productOptionService.getByMerchant(store, null, name, page, count); + ReadableProductOptionList valueList = new ReadableProductOptionList(); + valueList.setTotalPages(options.getTotalPages()); + valueList.setRecordsTotal(options.getTotalElements()); + valueList.setNumber(options.getNumber()); + + List values = options.getContent().stream() + .map(option -> readableMapper.convert(option, store, null)).collect(Collectors.toList()); + + valueList.setOptions(values); + + return valueList; + } + + @Override + public ReadableProductOptionEntity getOption(Long optionId, MerchantStore store, Language language) { + + Validate.notNull(optionId, "Option id cannot be null"); + Validate.notNull(store, "Store cannot be null"); + + ProductOption option = productOptionService.getById(store, optionId); + + if (option == null) { + throw new ResourceNotFoundException("Option id [" + optionId + "] not found"); + } + + return readableMapper.convert(option, store, language); + } + + @Override + public boolean optionExists(String code, MerchantStore store) { + Validate.notNull(code, "Option code must not be null"); + Validate.notNull(store, "Store code must not be null"); + boolean exists = false; + ProductOption option = productOptionService.getByCode(store, code); + if (option != null) { + exists = true; + } + return exists; + } + + @Override + public boolean optionValueExists(String code, MerchantStore store) { + Validate.notNull(code, "Option value code must not be null"); + Validate.notNull(store, "Store code must not be null"); + boolean exists = false; + ProductOptionValue optionValue = productOptionValueService.getByCode(store, code); + if (optionValue != null) { + exists = true; + } + return exists; + } + + @Override + public ReadableProductOptionValue saveOptionValue(PersistableProductOptionValue optionValue, + MerchantStore store, Language language) { + Validate.notNull(optionValue, "Option value code must not be null"); + Validate.notNull(store, "Store code must not be null"); + + ProductOptionValue value = new ProductOptionValue(); + if (optionValue.getId() != null && optionValue.getId().longValue() > 0) { + value = productOptionValueService.getById(store, optionValue.getId()); + if (value == null) { + throw new ResourceNotFoundException("ProductOptionValue [" + optionValue.getId() + + "] does not exists for store [" + store.getCode() + "]"); + } + } + + value = persistableOptionValueMapper.merge(optionValue, value, store, language); + + + try { + productOptionValueService.saveOrUpdate(value); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while saving option value", e); + } + + ProductOptionValue optValue = productOptionValueService.getById(store, value.getId()); + + // convert to readable + ReadableProductOptionValue readableProductOptionValue = new ReadableProductOptionValue(); + readableProductOptionValue = readableOptionValueMapper.merge(optValue, readableProductOptionValue, store, + language); + + return readableProductOptionValue; + } + + @Override + public ReadableProductOptionValue getOptionValue(Long optionValueId, MerchantStore store, Language language) { + + Validate.notNull(optionValueId, "OptionValue id cannot be null"); + Validate.notNull(store, "Store cannot be null"); + + ProductOptionValue optionValue = productOptionValueService.getById(store, optionValueId); + + if (optionValue == null) { + throw new ResourceNotFoundException("OptionValue id [" + optionValueId + "] not found"); + } + + return readableOptionValueMapper.convert(optionValue, store, language); + } + + @Override + public ReadableProductAttributeEntity saveAttribute(Long productId, PersistableProductAttribute attribute, + MerchantStore store, Language language) { + Validate.notNull(productId, "Product id cannot be null"); + Validate.notNull(attribute, "ProductAttribute cannot be null"); + Validate.notNull(attribute.getOption(), "ProductAttribute option cannot be null"); + Validate.notNull(attribute.getOptionValue(), "ProductAttribute option value cannot be null"); + Validate.notNull(store, "Store cannot be null"); + + attribute.setProductId(productId); + ProductAttribute attr = new ProductAttribute(); + if (attribute.getId() != null && attribute.getId().longValue() > 0) { + attr = productAttributeService.getById(attribute.getId()); + if (attr == null) { + throw new ResourceNotFoundException("Product attribute [" + attribute.getId() + "] not found"); + } + + if (productId != attr.getProduct().getId().longValue()) { + throw new ResourceNotFoundException( + "Product attribute [" + attribute.getId() + "] not found for product [" + productId + "]"); + } + } + + attr = persistableProductAttributeMapper.merge(attribute, attr, store, language); + + try { + productAttributeService.saveOrUpdate(attr); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while saving ProductAttribute", e); + } + + // refresh + attr = productAttributeService.getById(attr.getId()); + ReadableProductAttributeEntity readable = readableProductAttributeMapper.convert(attr, store, language); + + return readable; + } + + @Override + public ReadableProductAttributeEntity getAttribute(Long productId, Long attributeId, MerchantStore store, + Language language) { + + ProductAttribute attr = productAttributeService.getById(attributeId); + + if (attr == null) { + throw new ResourceNotFoundException( + "ProductAttribute not found for [" + attributeId + "] and store [" + store.getCode() + "]"); + } + + if (attr.getProduct().getId().longValue() != productId) { + throw new ResourceNotFoundException( + "ProductAttribute not found for [" + attributeId + "] and product [" + productId + "]"); + } + + if (attr.getProduct().getMerchantStore().getId().intValue() != store.getId().intValue()) { + throw new ResourceNotFoundException("ProductAttribute not found for [" + attributeId + "] and product [" + + productId + "] and store [" + store.getCode() + "]"); + } + + ReadableProductAttributeEntity readable = readableProductAttributeMapper.convert(attr, store, language); + + return readable; + } + + private Product product(long id, MerchantStore store) { + Product product = productService.getById(id); + + if (product == null) { + throw new ResourceNotFoundException("Productnot found for id [" + id + "]"); + } + + if (product.getMerchantStore().getId().intValue() != store.getId().intValue()) { + throw new ResourceNotFoundException( + "Productnot found id [" + id + "] for store [" + store.getCode() + "]"); + } + + return product; + } + + @Override + public ReadableProductAttributeList getAttributesList(Long productId, MerchantStore store, Language language, int page, int count) { + + try { + + Product product = this.product(productId, store); + + ReadableProductAttributeList attrList = new ReadableProductAttributeList(); + Page attr = null; + + + if(language != null) { //all entry + //attributes = productAttributeService.getByProductId(store, product, language); + attr = productAttributeService.getByProductId(store, product, language, page, count); + attrList.setRecordsTotal(attr.getTotalElements()); + attrList.setNumber(attr.getNumberOfElements()); + attrList.setTotalPages(attr.getTotalPages()); + } else { + attr = productAttributeService.getByProductId(store, product, page, count); + attrList.setRecordsTotal(attr.getTotalElements()); + attrList.setNumber(attr.getNumberOfElements()); + attrList.setTotalPages(attr.getTotalPages()); + } + + + List values = attr.getContent().stream() + .map(attribute -> readableProductAttributeMapper.convert(attribute, store, language)) + .collect(Collectors.toList()); + + attrList.setAttributes(values); + + return attrList; + + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while getting attributes", e); + } + + } + + @Override + public void deleteAttribute(Long productId, Long attributeId, MerchantStore store) { + try { + + ProductAttribute attr = productAttributeService.getById(attributeId); + if (attr == null) { + throw new ResourceNotFoundException( + "ProductAttribute not found for [" + attributeId + "] and store [" + store.getCode() + "]"); + } + + if (attr.getProduct().getId().longValue() != productId) { + throw new ResourceNotFoundException( + "ProductAttribute not found for [" + attributeId + "] and product [" + productId + "]"); + } + + if (attr.getProduct().getMerchantStore().getId().intValue() != store.getId().intValue()) { + throw new ResourceNotFoundException("ProductAttribute not found for [" + attributeId + "] and product [" + + productId + "] and store [" + store.getCode() + "]"); + } + + productAttributeService.delete(attr); + + } catch (ServiceException e) { + throw new ServiceRuntimeException( + "An exception occured while deleting ProductAttribute [" + attributeId + "]", e); + } + + } + + + + @Override + public void addOptionValueImage(MultipartFile image, Long optionValueId, + MerchantStore store, Language language) { + + + Validate.notNull(optionValueId,"OptionValueId must not be null"); + Validate.notNull(image,"Image must not be null"); + //get option value + ProductOptionValue value = productOptionValueService.getById(store, optionValueId); + if(value == null) { + throw new ResourceNotFoundException("Product option value [" + optionValueId + "] not found"); + } + + try { + String imageName = image.getOriginalFilename(); + InputStream inputStream = image.getInputStream(); + InputContentFile cmsContentImage = new InputContentFile(); + cmsContentImage.setFileName(imageName); + cmsContentImage.setMimeType(image.getContentType()); + cmsContentImage.setFile(inputStream); + + contentService.addOptionImage(store.getCode(), cmsContentImage); + value.setProductOptionValueImage(imageName); + productOptionValueService.saveOrUpdate(value); + } catch (Exception e) { + throw new ServiceRuntimeException("Exception while adding option value image", e); + } + + + + + return; + } + + @Override + public void removeOptionValueImage(Long optionValueId, MerchantStore store, + Language language) { + Validate.notNull(optionValueId,"OptionValueId must not be null"); + ProductOptionValue value = productOptionValueService.getById(store, optionValueId); + if(value == null) { + throw new ResourceNotFoundException("Product option value [" + optionValueId + "] not found"); + } + + try { + + contentService.removeFile(store.getCode(), FileContentType.PROPERTY, value.getProductOptionValueImage()); + value.setProductOptionValueImage(null); + productOptionValueService.saveOrUpdate(value); + } catch (Exception e) { + throw new ServiceRuntimeException("Exception while removing option value image", e); + } + + return; + } + + @Override + public List createAttributes(List attributes, Long productId, + MerchantStore store) { + Validate.notNull(productId,"Product id must not be null"); + Validate.notNull(store,"Merchant cannot be null"); + + //convert to model + + List modelAttributes = attributes.stream().map(attr -> persistableProductAttributeMapper.convert(attr, store, null)).collect(Collectors.toList()); + + try { + productAttributeService.saveAll(modelAttributes); + + //save to a product + Product product = this.product(productId, store); + product.getAttributes().addAll(modelAttributes); + + + productService.save(product); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while saving product with attributes", e); + } + + return modelAttributes.stream().map(e -> codeEntity(e)).collect(Collectors.toList()); + + } + + private CodeEntity codeEntity(ProductAttribute attr) { + CodeEntity entity = new CodeEntity(); + entity.setId(attr.getId()); + entity.setCode(attr.getProductOption().getCode()); + return entity; + } + + @Override + public void updateAttributes(List attributes, Long productId, MerchantStore store) { + // TODO Auto-generated method stub + throw new NotImplementedException("Method not implemented"); + + } + +} \ No newline at end of file diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductOptionSetFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductOptionSetFacadeImpl.java new file mode 100644 index 0000000000..014a140edd --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductOptionSetFacadeImpl.java @@ -0,0 +1,167 @@ +package com.salesmanager.shop.store.facade.product; + +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.product.attribute.ProductOptionSetService; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionSet; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.catalog.PersistableProductOptionSetMapper; +import com.salesmanager.shop.mapper.catalog.ReadableProductOptionSetMapper; +import com.salesmanager.shop.model.catalog.product.attribute.optionset.PersistableProductOptionSet; +import com.salesmanager.shop.model.catalog.product.attribute.optionset.ReadableProductOptionSet; +import com.salesmanager.shop.model.catalog.product.type.ReadableProductType; +import com.salesmanager.shop.store.api.exception.OperationNotAllowedException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.product.facade.ProductOptionSetFacade; +import com.salesmanager.shop.store.controller.product.facade.ProductTypeFacade; + +@Service +public class ProductOptionSetFacadeImpl implements ProductOptionSetFacade { + + @Autowired + private PersistableProductOptionSetMapper persistableProductOptionSetMapper; + + @Autowired + private ReadableProductOptionSetMapper readableProductOptionSetMapper; + + @Autowired + private ProductOptionSetService productOptionSetService; + + @Autowired + private ProductTypeFacade productTypeFacade;; + + @Override + public ReadableProductOptionSet get(Long id, MerchantStore store, Language language) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + ProductOptionSet optionSet = productOptionSetService.getById(store, id, language); + if (optionSet == null) { + throw new ResourceNotFoundException( + "ProductOptionSet not found for id [" + id + "] and store [" + store.getCode() + "]"); + } + + return readableProductOptionSetMapper.convert(optionSet, store, language); + } + + @Override + public List list(MerchantStore store, Language language) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + + try { + List optionSets = productOptionSetService.listByStore(store, language); + return optionSets.stream().map(opt -> this.convert(opt, store, language)).collect(Collectors.toList()); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while listing ProductOptionSet", e); + } + + } + + private ReadableProductOptionSet convert(ProductOptionSet optionSet, MerchantStore store, Language language) { + return readableProductOptionSetMapper.convert(optionSet, store, language); + } + + @Override + public void create(PersistableProductOptionSet optionSet, MerchantStore store, Language language) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + Validate.notNull(optionSet, "PersistableProductOptionSet cannot be null"); + + if (this.exists(optionSet.getCode(), store)) { + throw new OperationNotAllowedException("Option set with code [" + optionSet.getCode() + "] already exist"); + } + + ProductOptionSet opt = persistableProductOptionSetMapper.convert(optionSet, store, language); + try { + opt.setStore(store); + productOptionSetService.create(opt); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while creating ProductOptionSet", e); + } + + } + + @Override + public void update(Long id, PersistableProductOptionSet optionSet, MerchantStore store, Language language) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + Validate.notNull(optionSet, "PersistableProductOptionSet cannot be null"); + + ProductOptionSet opt = productOptionSetService.getById(store, id, language); + if (opt == null) { + throw new ResourceNotFoundException( + "ProductOptionSet not found for id [" + id + "] and store [" + store.getCode() + "]"); + } + + optionSet.setId(id); + optionSet.setCode(opt.getCode()); + ProductOptionSet model = persistableProductOptionSetMapper.convert(optionSet, store, language); + try { + model.setStore(store); + productOptionSetService.save(model); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while creating ProductOptionSet", e); + } + + } + + @Override + public void delete(Long id, MerchantStore store) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(id, "id cannot be null"); + ProductOptionSet opt = productOptionSetService.getById(id); + if (opt == null) { + throw new ResourceNotFoundException( + "ProductOptionSet not found for id [" + id + "] and store [" + store.getCode() + "]"); + } + if (!opt.getStore().getCode().equals(store.getCode())) { + throw new ResourceNotFoundException( + "ProductOptionSet not found for id [" + id + "] and store [" + store.getCode() + "]"); + } + try { + productOptionSetService.delete(opt); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while deleting ProductOptionSet", e); + } + + } + + @Override + public boolean exists(String code, MerchantStore store) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(code, "code cannot be null"); + ProductOptionSet optionSet = productOptionSetService.getCode(store, code); + if (optionSet != null) { + return true; + } + + return false; + } + + @Override + public List list(MerchantStore store, Language language, String type) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + Validate.notNull(type, "Product type cannot be null"); + + // find product type by id + ReadableProductType readable = productTypeFacade.get(store, type, language); + + if(readable == null) { + throw new ResourceNotFoundException("Can't fing product type [" + type + "] fpr merchand [" + store.getCode() +"]"); + } + + List optionSets = productOptionSetService.getByProductType(readable.getId(), store, language); + return optionSets.stream().map(opt -> this.convert(opt, store, language)).collect(Collectors.toList()); + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductPriceFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductPriceFacadeImpl.java new file mode 100644 index 0000000000..e4ebd84e4e --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductPriceFacadeImpl.java @@ -0,0 +1,150 @@ +package com.salesmanager.shop.store.facade.product; + +import static com.salesmanager.core.business.utils.NumberUtils.isPositive; +import java.util.List; +import java.util.stream.Collectors; + +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.catalog.product.availability.ProductAvailabilityService; +import com.salesmanager.core.business.services.catalog.product.price.ProductPriceService; +import com.salesmanager.core.model.catalog.product.availability.ProductAvailability; +import com.salesmanager.core.model.catalog.product.price.ProductPrice; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.inventory.PersistableProductPriceMapper; +import com.salesmanager.shop.model.catalog.product.PersistableProductPrice; +import com.salesmanager.shop.model.catalog.product.ReadableProductPrice; +import com.salesmanager.shop.populator.catalog.ReadableProductPricePopulator; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.product.facade.ProductPriceFacade; + +@Service +public class ProductPriceFacadeImpl implements ProductPriceFacade { + + + @Autowired + private ProductPriceService productPriceService; + + @Autowired + private PricingService pricingService; + + @Autowired + private ProductAvailabilityService productAvailabilityService; + + + @Autowired + private PersistableProductPriceMapper persistableProductPriceMapper; + + @Override + public Long save(PersistableProductPrice price, MerchantStore store) { + + + ProductPrice productPrice = persistableProductPriceMapper.convert(price, store, store.getDefaultLanguage()); + try { + if(!isPositive(productPrice.getId())) { + //avoid detached entity failed to persist + productPrice.getProductAvailability().setPrices(null); + productPrice = productPriceService + .saveOrUpdate(productPrice); + } else { + productPrice = productPriceService + .saveOrUpdate(productPrice); + } + + } catch (ServiceException e) { + throw new ServiceRuntimeException("An exception occured while creating a ProductPrice"); + } + return productPrice.getId(); + } + + + @Override + public List list(String sku, Long inventoryId, MerchantStore store, Language language) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(sku, "Product sku cannot be null"); + Validate.notNull(inventoryId, "Product inventory cannot be null"); + + List prices = productPriceService.findByInventoryId(inventoryId, sku, store); + List returnPrices = prices.stream().map(p -> { + try { + return this.readablePrice(p, store, language); + } catch (ConversionException e) { + throw new ServiceRuntimeException("An exception occured while getting product price for sku [" + sku + "] and Store [" + store.getCode() + "]", e); + } + }).collect(Collectors.toList()); + + return returnPrices; + + + } + + @Override + public List list(String sku, MerchantStore store, Language language) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(sku, "Product sku cannot be null"); + + List prices = productPriceService.findByProductSku(sku, store); + List returnPrices = prices.stream().map(p -> { + try { + return this.readablePrice(p, store, language); + } catch (ConversionException e) { + throw new ServiceRuntimeException("An exception occured while getting product price for sku [" + sku + "] and Store [" + store.getCode() + "]", e); + } + }).collect(Collectors.toList()); + + return returnPrices; + + } + + + @Override + public void delete(Long priceId, String sku, MerchantStore store) { + Validate.notNull(priceId, "Product Price id cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(sku, "Product sku cannot be null"); + ProductPrice productPrice = productPriceService.findById(priceId, sku, store); + if(productPrice == null) { + throw new ServiceRuntimeException("An exception occured while getting product price [" + priceId + "] for product sku [" + sku + "] and Store [" + store.getCode() + "]"); + } + + try { + productPriceService.delete(productPrice); + } catch (ServiceException e) { + throw new ServiceRuntimeException("An exception occured while deleting product price [" + priceId + "] for product sku [" + sku + "] and Store [" + store.getCode() + "]", e); + } + + } + + private ReadableProductPrice readablePrice (ProductPrice price, MerchantStore store, Language language) throws ConversionException { + ReadableProductPricePopulator populator = new ReadableProductPricePopulator(); + populator.setPricingService(pricingService); + return populator.populate(price, store, language); + } + + + @Override + public ReadableProductPrice get(String sku, Long productPriceId, MerchantStore store, Language language) { + Validate.notNull(productPriceId, "Product Price id cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(sku, "Product sku cannot be null"); + ProductPrice price = productPriceService.findById(productPriceId, sku, store); + + if(price == null) { + throw new ResourceNotFoundException("ProductPrice with id [" + productPriceId + " not found for product sku [" + sku + "] and Store [" + store.getCode() + "]"); + } + + try { + return readablePrice(price, store, language); + } catch (ConversionException e) { + throw new ServiceRuntimeException("An exception occured while deleting product price [" + productPriceId + "] for product sku [" + sku + "] and Store [" + store.getCode() + "]", e); + } + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductTypeFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductTypeFacadeImpl.java new file mode 100644 index 0000000000..73f5dffe0a --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductTypeFacadeImpl.java @@ -0,0 +1,202 @@ +package com.salesmanager.shop.store.facade.product; + +import java.util.stream.Collectors; + +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.product.type.ProductTypeService; +import com.salesmanager.core.model.catalog.product.type.ProductType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.catalog.PersistableProductTypeMapper; +import com.salesmanager.shop.mapper.catalog.ReadableProductTypeMapper; +import com.salesmanager.shop.model.catalog.product.type.PersistableProductType; +import com.salesmanager.shop.model.catalog.product.type.ReadableProductType; +import com.salesmanager.shop.model.catalog.product.type.ReadableProductTypeList; +import com.salesmanager.shop.store.api.exception.OperationNotAllowedException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.product.facade.ProductTypeFacade; + +@Service("productTypeFacade") +public class ProductTypeFacadeImpl implements ProductTypeFacade { + + @Autowired + private ProductTypeService productTypeService; + + @Autowired + private ReadableProductTypeMapper readableProductTypeMapper; + + @Autowired + private PersistableProductTypeMapper persistableProductTypeMapper; + + @Override + public ReadableProductTypeList getByMerchant(MerchantStore store, Language language, int count, int page) { + + Validate.notNull(store, "MerchantStore cannot be null"); + ReadableProductTypeList returnList = new ReadableProductTypeList(); + + try { + + Page types = productTypeService.getByMerchant(store, language, page, count); + + if(types != null) { + returnList.setList(types.getContent().stream().map(t -> readableProductTypeMapper.convert(t, store, language)).collect(Collectors.toList())); + returnList.setTotalPages(types.getTotalPages()); + returnList.setRecordsTotal(types.getTotalElements()); + returnList.setRecordsFiltered(types.getSize()); + } + + return returnList; + } catch (Exception e) { + throw new ServiceRuntimeException( + "An exception occured while getting product types for merchant[ " + store.getCode() + "]", e); + } + + } + + @Override + public ReadableProductType get(MerchantStore store, Long id, Language language) { + + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(id, "ProductType code cannot be empty"); + try { + + ProductType type = null; + if(language == null) { + type = productTypeService.getById(id, store); + } else { + type = productTypeService.getById(id, store, language); + } + + if(type == null) { + throw new ResourceNotFoundException("Product type [" + id + "] not found for store [" + store.getCode() + "]"); + } + + ReadableProductType readableType = readableProductTypeMapper.convert(type, store, language); + + + return readableType; + + } catch(Exception e) { + throw new ServiceRuntimeException( + "An exception occured while getting product type [" + id + "] not found for store [" + store.getCode() + "]", e); + } + + } + + @Override + public Long save(PersistableProductType type, MerchantStore store, Language language) { + + Validate.notNull(type,"ProductType cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null"); + Validate.notNull(type.getCode(),"ProductType code cannot be empty"); + + try { + + if(this.exists(type.getCode(), store, language)) { + throw new OperationNotAllowedException( + "Product type [" + type.getCode() + "] already exist for store [" + store.getCode() + "]"); + } + + ProductType model = persistableProductTypeMapper.convert(type, store, language); + model.setMerchantStore(store); + ProductType saved = productTypeService.saveOrUpdate(model); + return saved.getId(); + + } catch(Exception e) { + throw new ServiceRuntimeException( + "An exception occured while saving product type",e); + } + + } + + @Override + public void update(PersistableProductType type, Long id, MerchantStore store, Language language) { + Validate.notNull(type,"ProductType cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null"); + Validate.notNull(id,"id cannot be empty"); + + try { + + ProductType t = productTypeService.getById(id, store, language); + if(t == null) { + throw new ResourceNotFoundException( + "Product type [" + type.getCode() + "] does not exist for store [" + store.getCode() + "]"); + } + + type.setId(t.getId()); + type.setCode(t.getCode()); + + ProductType model = persistableProductTypeMapper.merge(type, t, store, language); + model.setMerchantStore(store); + productTypeService.saveOrUpdate(model); + + } catch(Exception e) { + throw new ServiceRuntimeException( + "An exception occured while saving product type",e); + } + + } + + @Override + public void delete(Long id, MerchantStore store, Language language) { + Validate.notNull(store,"MerchantStore cannot be null"); + Validate.notNull(id,"id cannot be empty"); + + try { + + ProductType t = productTypeService.getById(id, store, language); + if(t == null) { + throw new ResourceNotFoundException( + "Product type [" + id + "] does not exist for store [" + store.getCode() + "]"); + } + + productTypeService.delete(t); + + + } catch(Exception e) { + throw new ServiceRuntimeException( + "An exception occured while saving product type",e); + } + + } + + @Override + public boolean exists(String code, MerchantStore store, Language language) { + ProductType t; + try { + t = productTypeService.getByCode(code, store, language); + } catch (ServiceException e) { + throw new RuntimeException("An exception occured while getting product type [" + code + "] for merchant store [" + store.getCode() +"]",e); + } + if(t != null) { + return true; + } + return false; + } + + @Override + public ReadableProductType get(MerchantStore store, String code, Language language) { + ProductType t; + try { + t = productTypeService.getByCode(code, store, language); + } catch (ServiceException e) { + throw new RuntimeException("An exception occured while getting product type [" + code + "] for merchant store [" + store.getCode() +"]",e); + } + + if(t == null) { + throw new ResourceNotFoundException("Product type [" + code + "] not found for merchant [" + store.getCode() + "]"); + } + + ReadableProductType readableType = readableProductTypeMapper.convert(t, store, language); + return readableType; + + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductVariantFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductVariantFacadeImpl.java new file mode 100644 index 0000000000..230ab8e26a --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductVariantFacadeImpl.java @@ -0,0 +1,201 @@ +package com.salesmanager.shop.store.facade.product; + +import static com.salesmanager.shop.util.ReadableEntityUtil.createReadableList; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.product.variant.ProductVariantService; +import com.salesmanager.core.business.services.catalog.product.variation.ProductVariationService; +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.catalog.product.variation.ProductVariation; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.catalog.product.PersistableProductVariantMapper; +import com.salesmanager.shop.mapper.catalog.product.ReadableProductVariantMapper; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.model.catalog.product.product.variant.PersistableProductVariant; +import com.salesmanager.shop.model.catalog.product.product.variant.ReadableProductVariant; +import com.salesmanager.shop.model.entity.ReadableEntityList; +import com.salesmanager.shop.store.api.exception.ConstraintException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.product.facade.ProductCommonFacade; +import com.salesmanager.shop.store.controller.product.facade.ProductFacade; +import com.salesmanager.shop.store.controller.product.facade.ProductVariantFacade; + + +/** + * Product instance management facade + * @author carlsamson + * + */ +@Component +public class ProductVariantFacadeImpl implements ProductVariantFacade { + + + @Autowired + private ReadableProductVariantMapper readableProductVariantMapper; + + @Autowired + private PersistableProductVariantMapper persistableProductVariantMapper; + + @Autowired + private ProductVariantService productVariantService; + + + @Autowired + private ProductVariationService productVariationService; + + @Autowired + private ProductFacade productFacade; + + @Autowired + private ProductCommonFacade productCommonFacade; + + @Override + public ReadableProductVariant get(Long instanceId, Long productId, MerchantStore store, Language language) { + Optional productVariant = this.getproductVariant(instanceId, productId, store); + + if(productVariant.isEmpty()) { + throw new ResourceNotFoundException("Product instance + [" + instanceId + "] not found for store [" + store.getCode() + "]"); + } + + + ProductVariant model = productVariant.get(); + return readableProductVariantMapper.convert(model, store, language); + + + } + + @Override + public boolean exists(String sku, MerchantStore store, Long productId, Language language) { + ReadableProduct product = null; + try { + product = productCommonFacade.getProduct(store, productId, language); + } catch (Exception e) { + throw new ServiceRuntimeException("Error while getting product [" + productId + "]",e); + } + + return productVariantService.exist(sku,product.getId()); + } + + @Override + public Long create(PersistableProductVariant productVariant, Long productId, MerchantStore store, + Language language) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(productVariant, "productVariant cannot be null"); + Validate.notNull(productId, "Product id cannot be null"); + + //variation and variation value should not be of same product option code + if( + productVariant.getVariation() != null && productVariant.getVariation().longValue() > 0 && + productVariant.getVariationValue() != null && productVariant.getVariationValue().longValue() > 0) + { + + List variations = productVariationService.getByIds(Arrays.asList(productVariant.getVariation(),productVariant.getVariationValue()), store); + + boolean differentOption = variations.stream().map(i -> i.getProductOption().getCode()).distinct().count() > 1; + + if(!differentOption) { + throw new ConstraintException("Product option of instance.variant and instance.variantValue must be different"); + } + + } + + + productVariant.setProductId(productId); + productVariant.setId(null); + ProductVariant variant = persistableProductVariantMapper.convert(productVariant, store, language); + + try { + productVariantService.saveProductVariant(variant); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Cannot save product instance for store [" + store.getCode() + "] and productId [" + productId + "]", e); + } + + return variant.getId(); + } + + @Override + public void update(Long instanceId, PersistableProductVariant productVariant, Long productId, MerchantStore store, Language language) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(productVariant, "productVariant cannot be null"); + Validate.notNull(productId, "Product id cannot be null"); + Validate.notNull(instanceId, "Product instance id cannot be null"); + + Optional instanceModel = this.getproductVariant(instanceId, productId, store); + if(instanceModel.isEmpty()) { + throw new ResourceNotFoundException("productVariant with id [" + instanceId + "] not found for store [" + store.getCode() + "] and productId [" + productId + "]"); + } + + productVariant.setProductId(productId); + + ProductVariant mergedModel = persistableProductVariantMapper.merge(productVariant, instanceModel.get(), store, language); + try { + productVariantService.saveProductVariant(mergedModel); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Cannot save product instance for store [" + store.getCode() + "] and productId [" + productId + "]", e); + } + + } + + private Optional getproductVariant(Long id, Long productId, MerchantStore store) { + return productVariantService.getById(id, productId, store); + } + + + @Override + public void delete(Long productVariant, Long productId, MerchantStore store) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(productVariant, "productVariant id cannot be null"); + Validate.notNull(productId, "Product id cannot be null"); + + + Optional instanceModel = this.getproductVariant(productVariant, productId, store); + if(instanceModel.isEmpty()) { + throw new ResourceNotFoundException("productVariant with id [" + productVariant + "] not found for store [" + store.getCode() + "] and productId [" + productId + "]"); + } + + try { + productVariantService.delete(instanceModel.get()); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Cannot delete product instance [" + productVariant + "] for store [" + store.getCode() + "] and productId [" + productId + "]", e); + } + + } + + @Override + public ReadableEntityList list(Long productId, MerchantStore store, Language language, + int page, int count) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(productId, "Product id cannot be null"); + + Product product = productFacade.getProduct(productId, store); + + if(product == null) { + throw new ResourceNotFoundException("Product with id [" + productId + "] not found for store [" + store.getCode() + "]"); + } + + Page instances = productVariantService.getByProductId(store, product, language, page, count); + + + List readableInstances = instances.stream() + .map(rp -> this.readableProductVariantMapper.convert(rp, store, language)).collect(Collectors.toList()); + + + return createReadableList(instances, readableInstances); + + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductVariantGroupFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductVariantGroupFacadeImpl.java new file mode 100644 index 0000000000..f9f0ea8b17 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductVariantGroupFacadeImpl.java @@ -0,0 +1,218 @@ +package com.salesmanager.shop.store.facade.product; + +import static com.salesmanager.shop.util.ReadableEntityUtil.createReadableList; + +import java.io.InputStream; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.jsoup.helper.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.product.variant.ProductVariantGroupService; +import com.salesmanager.core.business.services.catalog.product.variant.ProductVariantImageService; +import com.salesmanager.core.business.services.catalog.product.variant.ProductVariantService; +import com.salesmanager.core.business.services.content.ContentService; +import com.salesmanager.core.model.catalog.product.variant.ProductVariantImage; +import com.salesmanager.core.model.catalog.product.variant.ProductVariant; +import com.salesmanager.core.model.catalog.product.variant.ProductVariantGroup; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.content.InputContentFile; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.catalog.product.PersistableProductVariantGroupMapper; +import com.salesmanager.shop.mapper.catalog.product.ReadableProductVariantGroupMapper; +import com.salesmanager.shop.model.catalog.product.product.variantGroup.PersistableProductVariantGroup; +import com.salesmanager.shop.model.catalog.product.product.variantGroup.ReadableProductVariantGroup; +import com.salesmanager.shop.model.entity.ReadableEntityList; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.product.facade.ProductVariantGroupFacade; + + +@Component +public class ProductVariantGroupFacadeImpl implements ProductVariantGroupFacade { + + @Autowired + private ProductVariantGroupService productVariantGroupService; + + @Autowired + private ProductVariantService productVariantService; + + @Autowired + private ProductVariantImageService productVariantImageService; + + @Autowired + private PersistableProductVariantGroupMapper persistableProductIntanceGroupMapper; + + @Autowired + private ReadableProductVariantGroupMapper readableProductVariantGroupMapper; + + @Autowired + private ContentService contentService; //file management + + @Override + public ReadableProductVariantGroup get(Long instanceGroupId, MerchantStore store, Language language) { + + ProductVariantGroup group = this.group(instanceGroupId, store); + return readableProductVariantGroupMapper.convert(group, store, language); + } + + @Override + public Long create(PersistableProductVariantGroup productVariantGroup, MerchantStore store, Language language) { + + ProductVariantGroup group = persistableProductIntanceGroupMapper.convert(productVariantGroup, store, language); + try { + group = productVariantGroupService.saveOrUpdate(group); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Cannot save product instance group [" + productVariantGroup + "] for store [" + store.getCode() + "]"); + } + + return group.getId(); + } + + @Override + public void update(Long productVariantGroup, PersistableProductVariantGroup instance, MerchantStore store, + Language language) { + ProductVariantGroup group = this.group(productVariantGroup, store); + instance.setId(productVariantGroup); + + group = persistableProductIntanceGroupMapper.merge(instance, group, store, language); + + try { + productVariantGroupService.saveOrUpdate(group); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Cannot save product instance group [" + productVariantGroup + "] for store [" + store.getCode() + "]"); + } + + } + + @Override + public void delete(Long productVariantGroup, Long productId, MerchantStore store) { + + ProductVariantGroup group = this.group(productVariantGroup, store); + + if(group == null) { + throw new ResourceNotFoundException("Product instance group [" + group.getId() + " not found for store [" + store.getCode() + "]"); + } + + try { + + //null all group from instances + for(ProductVariant instance : group.getProductVariants()) { + Optional p = productVariantService.getById(instance.getId(), store); + if(p.isEmpty()) { + throw new ResourceNotFoundException("Product instance [" + instance.getId() + " not found for store [" + store.getCode() + "]"); + } + instance.setProductVariantGroup(null); + productVariantService.save(instance); + } + + //now delete + productVariantGroupService.delete(group); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Cannot remove product instance group [" + productVariantGroup + "] for store [" + store.getCode() + "]"); + } + + } + + @Override + public ReadableEntityList list(Long productId, MerchantStore store, Language language, + int page, int count) { + + + Page groups = productVariantGroupService.getByProductId(store, productId, language, page, count); + + List readableInstances = groups.stream() + .map(rp -> this.readableProductVariantGroupMapper.convert(rp, store, language)).collect(Collectors.toList()); + + return createReadableList(groups, readableInstances); + + } + + + private ProductVariantGroup group(Long productOptionGroupId,MerchantStore store) { + Optional group = productVariantGroupService.getById(productOptionGroupId, store); + if(group.isEmpty()) { + throw new ResourceNotFoundException("Product instance group [" + productOptionGroupId + "] not found"); + } + + return group.get(); + } + + @Override + public void addImage(MultipartFile image, Long instanceGroupId, + MerchantStore store, Language language) { + + + Validate.notNull(instanceGroupId,"productVariantGroupId must not be null"); + Validate.notNull(image,"Image must not be null"); + Validate.notNull(store,"MerchantStore must not be null"); + //get option group + + ProductVariantGroup group = this.group(instanceGroupId, store); + ProductVariantImage instanceImage = new ProductVariantImage(); + + try { + + String path = new StringBuilder().append("group").append(Constants.SLASH).append(instanceGroupId).toString(); + + + + instanceImage.setProductImage(image.getOriginalFilename()); + instanceImage.setProductVariantGroup(group); + String imageName = image.getOriginalFilename(); + InputStream inputStream = image.getInputStream(); + InputContentFile cmsContentImage = new InputContentFile(); + cmsContentImage.setFileName(imageName); + cmsContentImage.setMimeType(image.getContentType()); + cmsContentImage.setFile(inputStream); + cmsContentImage.setPath(path); + cmsContentImage.setFileContentType(FileContentType.VARIANT); + + contentService.addContentFile(store.getCode(), cmsContentImage); + + group.getImages().add(instanceImage); + + productVariantGroupService.saveOrUpdate(group); + } catch (Exception e) { + throw new ServiceRuntimeException("Exception while adding instance group image", e); + } + + + return; + } + + @Override + public void removeImage(Long imageId, Long productVariantGroupId, MerchantStore store) { + + Validate.notNull(productVariantGroupId,"productVariantGroupId must not be null"); + Validate.notNull(store,"MerchantStore must not be null"); + + ProductVariantImage image = productVariantImageService.getById(imageId); + + if(image == null) { + throw new ResourceNotFoundException("productVariantImage [" + imageId + "] was not found"); + } + + ProductVariantGroup group = this.group(productVariantGroupId, store); + + + try { + contentService.removeFile(Constants.SLASH + store.getCode() + Constants.SLASH + productVariantGroupId, FileContentType.VARIANT, image.getProductImage()); + group.getImages().removeIf(i -> (i.getId() == image.getId())); + //update productVariantroup + productVariantGroupService.update(group); + } catch (ServiceException e) { + throw new ServiceRuntimeException("An exception occured while removing instance image [" + imageId + "]",e); + } + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductVariationFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductVariationFacadeImpl.java new file mode 100644 index 0000000000..10f27419df --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/product/ProductVariationFacadeImpl.java @@ -0,0 +1,154 @@ +package com.salesmanager.shop.store.facade.product; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.catalog.product.variation.ProductVariationService; +import com.salesmanager.core.model.catalog.product.variation.ProductVariation; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.mapper.catalog.PersistableProductVariationMapper; +import com.salesmanager.shop.mapper.catalog.ReadableProductVariationMapper; +import com.salesmanager.shop.model.catalog.product.variation.PersistableProductVariation; +import com.salesmanager.shop.model.catalog.product.variation.ReadableProductVariation; +import com.salesmanager.shop.model.entity.ReadableEntityList; +import com.salesmanager.shop.store.api.exception.OperationNotAllowedException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.product.facade.ProductVariationFacade; + +@Service +public class ProductVariationFacadeImpl implements ProductVariationFacade { + + @Autowired + private PersistableProductVariationMapper persistableProductVariationMapper; + + @Autowired + private ReadableProductVariationMapper readableProductVariationMapper; + + @Autowired + private ProductVariationService productVariationService; + + + + @Override + public ReadableProductVariation get(Long variationId, MerchantStore store, Language language) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + Optional variation = productVariationService.getById(store, variationId, language); + if(variation.isEmpty()) { + throw new ResourceNotFoundException("ProductVariation not found for id [" + variationId +"] and store [" + store.getCode() + "]"); + } + + return readableProductVariationMapper.convert(variation.get(), store, language); + } + + @Override + public ReadableEntityList list(MerchantStore store, Language language, int page, int count) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + + + Page vars = productVariationService.getByMerchant(store, language, null, page, count); + List variations = vars.stream().map(opt -> this.convert(opt, store, language)).collect(Collectors.toList()); + ReadableEntityList returnList = new ReadableEntityList(); + returnList.setItems(variations); + returnList.setNumber(variations.size()); + returnList.setRecordsTotal(vars.getTotalElements()); + returnList.setTotalPages(vars.getTotalPages()); + return returnList; + + + } + + private ReadableProductVariation convert(ProductVariation var, MerchantStore store, Language language) { + return readableProductVariationMapper.convert(var, store, language); + } + + @Override + public Long create(PersistableProductVariation var, MerchantStore store, Language language) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + Validate.notNull(var, "PersistableProductVariation cannot be null"); + + if(this.exists(var.getCode(), store)) { + throw new OperationNotAllowedException("Option set with code [" + var.getCode() + "] already exist"); + } + + ProductVariation p = persistableProductVariationMapper.convert(var, store, language); + p.setMerchantStore(store); + try { + productVariationService.saveOrUpdate(p); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while creating ProductOptionSet", e); + } + + return p.getId(); + + } + + + @Override + public void update(Long variationId, PersistableProductVariation var, MerchantStore store, Language language) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(language, "Language cannot be null"); + Validate.notNull(var, "PersistableProductVariation cannot be null"); + + Optional p = productVariationService.getById(store, variationId, language); + if(p.isEmpty()) { + throw new ResourceNotFoundException("ProductVariation not found for id [" + variationId +"] and store [" + store.getCode() + "]"); + } + + ProductVariation productVariant = p.get(); + + productVariant.setId(variationId); + productVariant.setCode(var.getCode()); + ProductVariation model = persistableProductVariationMapper.merge(var, productVariant, store, language); + try { + model.setMerchantStore(store); + productVariationService.save(model); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while creating ProductVariation", e); + } + + } + + @Override + public void delete(Long variationId, MerchantStore store) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(variationId, "variationId cannot be null"); + ProductVariation opt = productVariationService.getById(variationId); + if(opt == null) { + throw new ResourceNotFoundException("ProductVariation not found for id [" + variationId +"] and store [" + store.getCode() + "]"); + } + if(!opt.getMerchantStore().getCode().equals(store.getCode())) { + throw new ResourceNotFoundException("ProductVariation not found for id [" + variationId +"] and store [" + store.getCode() + "]"); + } + try { + productVariationService.delete(opt); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Exception while deleting ProductVariation", e); + } + + } + + @Override + public boolean exists(String code, MerchantStore store) { + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(code, "code cannot be null"); + Optional var = productVariationService.getByCode(store, code); + if(var.isPresent()) { + return true; + } + + return false; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/shipping/ShippingConfigurationFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/shipping/ShippingConfigurationFacadeImpl.java new file mode 100644 index 0000000000..d9e297f9ca --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/shipping/ShippingConfigurationFacadeImpl.java @@ -0,0 +1,39 @@ +package com.salesmanager.shop.store.facade.shipping; + +import java.util.List; + +import org.springframework.stereotype.Service; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.shop.model.configuration.PersistableConfiguration; +import com.salesmanager.shop.model.configuration.ReadableConfiguration; +import com.salesmanager.shop.store.controller.configurations.ConfigurationsFacade; + +@Service("shippingConfigurationFacade") +public class ShippingConfigurationFacadeImpl implements ConfigurationsFacade { + + @Override + public List configurations(MerchantStore store) { + // TODO Auto-generated method stub + return null; + } + + @Override + public ReadableConfiguration configuration(String module, MerchantStore store) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void saveConfiguration(PersistableConfiguration configuration, MerchantStore store) { + // TODO Auto-generated method stub + + } + + @Override + public void deleteConfiguration(String module, MerchantStore store) { + // TODO Auto-generated method stub + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/shoppingCart/ShoppingCartFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/shoppingCart/ShoppingCartFacadeImpl.java new file mode 100644 index 0000000000..534c59c508 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/shoppingCart/ShoppingCartFacadeImpl.java @@ -0,0 +1,73 @@ +package com.salesmanager.shop.store.facade.shoppingCart; + +import java.util.Optional; + +import org.apache.commons.lang3.Validate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.shoppingcart.ShoppingCartService; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.shoppingcart.ShoppingCart; +import com.salesmanager.shop.model.shoppingcart.ReadableShoppingCart; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.shoppingCart.facade.v1.ShoppingCartFacade; + +@Service("shoppingCartFacadev1") +public class ShoppingCartFacadeImpl implements ShoppingCartFacade { + + @Autowired + private CustomerService customerService; + + @Autowired + private ShoppingCartService shoppingCartService; + + @Autowired + private com.salesmanager.shop.store.controller.customer.facade.CustomerFacade customerFacade; + + @Autowired + private com.salesmanager.shop.store.controller.shoppingCart.facade.ShoppingCartFacade shoppingCartFacade; // legacy + // facade + + @Override + public ReadableShoppingCart get(Optional cart, Long customerId, MerchantStore store, Language language) { + + Validate.notNull(customerId, "Customer id cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + + try { + + // lookup customer + Customer customer = customerService.getById(customerId); + + if (customer == null) { + throw new ResourceNotFoundException("No Customer found for id [" + customerId + "]"); + } + + ShoppingCart cartModel = shoppingCartService.getShoppingCart(customer, store); + + if(cart.isPresent()) { + cartModel = customerFacade.mergeCart(customer, cart.get(), store, language); + } + + if(cartModel == null) { + return null; + } + + ReadableShoppingCart readableCart = shoppingCartFacade.readableCart(cartModel, store, language); + + return readableCart; + + } catch (Exception e) { + + throw new ServiceRuntimeException(e); + + } + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/tax/TaxFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/tax/TaxFacadeImpl.java new file mode 100644 index 0000000000..08569942d4 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/tax/TaxFacadeImpl.java @@ -0,0 +1,354 @@ +package com.salesmanager.shop.store.facade.tax; + +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.tax.TaxClassService; +import com.salesmanager.core.business.services.tax.TaxRateService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.tax.taxclass.TaxClass; +import com.salesmanager.core.model.tax.taxrate.TaxRate; +import com.salesmanager.shop.mapper.tax.PersistableTaxClassMapper; +import com.salesmanager.shop.mapper.tax.PersistableTaxRateMapper; +import com.salesmanager.shop.mapper.tax.ReadableTaxClassMapper; +import com.salesmanager.shop.mapper.tax.ReadableTaxRateMapper; +import com.salesmanager.shop.model.entity.Entity; +import com.salesmanager.shop.model.entity.ReadableEntityList; +import com.salesmanager.shop.model.tax.PersistableTaxClass; +import com.salesmanager.shop.model.tax.PersistableTaxRate; +import com.salesmanager.shop.model.tax.ReadableTaxClass; +import com.salesmanager.shop.model.tax.ReadableTaxRate; +import com.salesmanager.shop.store.api.exception.OperationNotAllowedException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.api.exception.UnauthorizedException; +import com.salesmanager.shop.store.controller.tax.facade.TaxFacade; + +@Service +public class TaxFacadeImpl implements TaxFacade { + + private static final Logger LOGGER = LoggerFactory.getLogger(TaxFacadeImpl.class); + + + @Autowired + private TaxClassService taxClassService; + + @Autowired + private TaxRateService taxRateService; + + @Autowired + private PersistableTaxClassMapper persistableTaxClassMapper; + + @Autowired + private ReadableTaxClassMapper readableTaxClassMapper; + + @Autowired + private PersistableTaxRateMapper persistableTaxRateMapper; + + @Autowired + private ReadableTaxRateMapper readableTaxRateMapper; + + @Override + public Entity createTaxClass(PersistableTaxClass taxClass, MerchantStore store, Language language) { + Validate.notNull(taxClass,"TaxClass cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null"); + Validate.notNull(store.getCode(),"MerchantStore code cannot be null"); + try { + + + if(this.existsTaxClass(taxClass.getCode(), store, language)) { + throw new OperationNotAllowedException("Tax class [" + taxClass.getCode() + "] already exist for store [" + store.getCode() + "]"); + } + + taxClass.setStore(store.getCode()); + TaxClass model = persistableTaxClassMapper.convert(taxClass, store, language); + model = taxClassService.saveOrUpdate(model);; + Entity id = new Entity(); + id.setId(model.getId()); + return id; + + } catch (ServiceException e) { + LOGGER.error("Error while saving taxClass [" + taxClass.getCode() + "] for store [" + store.getCode() + "]", e); + throw new ServiceRuntimeException("Error while saving taxClass [" + taxClass.getCode() + "] for store [" + store.getCode() + "]", e); + } + + } + + @Override + public void deleteTaxClass(Long id, MerchantStore store, Language language) { + Validate.notNull(id,"TaxClass id cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null"); + Validate.notNull(store.getCode(),"MerchantStore code cannot be null"); + try { + TaxClass model = taxClassService.getById(id); + if(model == null) { + throw new ResourceNotFoundException("TaxClass not found [" + id + "] for store [" + store.getCode() + "]"); + } else { + if(!model.getMerchantStore().getCode().equals(store.getCode())) { + throw new UnauthorizedException("MerchantStore [" + store.getCode() + "] cannot delete tax class [" + id + "]"); + } + } + taxClassService.delete(model); + + } catch (ServiceException e) { + LOGGER.error("Error while getting taxClasse [" + id + "] for store [" + store.getCode() + "]", e); + throw new ServiceRuntimeException("Error while getting taxClasse [" + id + "] for store [" + store.getCode() + "]", e); + } + + } + + @Override + public ReadableEntityList taxClasses(MerchantStore store, Language language) { + Validate.notNull(store,"MerchantStore cannot be null"); + Validate.notNull(store.getCode(),"MerchantStore code cannot be null"); + try { + List models = taxClassService.listByStore(store); + + List taxClasses = models.stream().map(t -> convertToReadableTaxClass(t, store, language)).collect(Collectors.toList()); + + ReadableEntityList list = new ReadableEntityList(); + list.setItems(taxClasses); + list.setNumber(taxClasses.size()); + list.setTotalPages(1); + list.setRecordsTotal(taxClasses.size()); + + return list; + + } catch (ServiceException e) { + LOGGER.error("Error while getting taxClasses for store [" + store.getCode() + "]", e); + throw new ServiceRuntimeException("Error while getting taxClasses for store [" + store.getCode() + "]", e); + } + } + + private ReadableTaxClass convertToReadableTaxClass(TaxClass t, MerchantStore store, Language language) { + return readableTaxClassMapper.convert(t, store, language); + } + + @Override + public void updateTaxClass(Long id, PersistableTaxClass taxClass, MerchantStore store, Language language) { + Validate.notNull(taxClass,"TaxClass cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null"); + Validate.notNull(store.getCode(),"MerchantStore code cannot be null"); + try { + TaxClass model = taxClassService.getById(id); + if(model == null) { + throw new ResourceNotFoundException("TaxClass not found [" + id + "] for store [" + store.getCode() + "]"); + } else { + if(!model.getMerchantStore().getCode().equals(store.getCode())) { + throw new UnauthorizedException("MerchantStore [" + store.getCode() + "] cannot update tax class [" + taxClass.getCode() + "]"); + } + } + model = persistableTaxClassMapper.convert(taxClass, store, language); + taxClassService.saveOrUpdate(model); + + } catch (ServiceException e) { + LOGGER.error("Error while saving taxClass [" + taxClass.getCode() + "] for store [" + store.getCode() + "]", e); + throw new ServiceRuntimeException("Error while saving taxClass [" + taxClass.getCode() + "] for store [" + store.getCode() + "]", e); + } + } + + @Override + public ReadableTaxClass taxClass(String code, MerchantStore store, Language language) { + + Validate.notNull(code,"TaxClass code cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null"); + Validate.notNull(store.getCode(),"MerchantStore code cannot be null"); + + try { + TaxClass model = taxClassService.getByCode(code, store); + if(model == null) { + throw new ResourceNotFoundException("TaxClass not found [" + code + "] for store [" + store.getCode() + "]"); + } + if(model != null) { + if(!model.getMerchantStore().getCode().equals(store.getCode())) { + throw new UnauthorizedException("MerchantStore [" + store.getCode() + "] cannot get tax class [" + code + "]"); + } + } + return readableTaxClassMapper.convert(model, store, language); + } catch (ServiceException e) { + LOGGER.error("Error while getting taxClass [" + code + "] for store [" + store.getCode() + "]", e); + throw new ServiceRuntimeException("Error while getting taxClass [" + code + "] for store [" + store.getCode() + "]", e); + } + + } + + @Override + public boolean existsTaxClass(String code, MerchantStore store, Language language) { + try { + boolean exist = taxClassService.exists(code, store); + return exist; + } catch (ServiceException e) { + LOGGER.error("Error while getting taxClass [" + code + "] for store [" + store.getCode() + "]", e); + throw new ServiceRuntimeException("Error while saving taxClass [" + code + "] for store [" + store.getCode() + "]", e); + } + } + + + //get by code + private TaxRate taxRateByCode(String code, MerchantStore store, Language language) { + + Validate.notNull(code,"TaxRate code cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null"); + Validate.notNull(store.getCode(),"MerchantStore code cannot be null"); + + try { + TaxRate model = taxRateService.getByCode(code, store); + if(model == null) { + throw new ResourceNotFoundException("TaxRate not found [" + code + "] for store [" + store.getCode() + "]"); + } + if(model != null) { + if(!model.getMerchantStore().getCode().equals(store.getCode())) { + throw new UnauthorizedException("MerchantStore [" + store.getCode() + "] cannot get tax rate [" + code + "]"); + } + } + return model; + } catch (ServiceException e) { + LOGGER.error("Error while getting taxRate [" + code + "] for store [" + store.getCode() + "]", e); + throw new ServiceRuntimeException("Error while getting taxRate [" + code + "] for store [" + store.getCode() + "]", e); + } + + } + + //get by id + private TaxRate taxRateById(Long id, MerchantStore store, Language language) { + + Validate.notNull(id,"TaxRate id cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null"); + Validate.notNull(store.getCode(),"MerchantStore code cannot be null"); + + try { + TaxRate model = taxRateService.getById(id, store); + if(model == null) { + throw new ResourceNotFoundException("TaxRate not found [" + id + "]"); + } + return model; + } catch (Exception e) { + LOGGER.error("Error while getting taxRate [" + id + "] for store [" + store.getCode() + "]", e); + throw new ServiceRuntimeException("Error while getting taxRate [" + id + "] for store [" + store.getCode() + "]", e); + } + + } + + + @Override + public void deleteTaxRate(Long id, MerchantStore store, Language language) { + TaxRate model = taxRateById(id, store, language); + try { + taxRateService.delete(model); + } catch (ServiceException e) { + LOGGER.error("Error while deleting taxRate [" + id + "] for store [" + store.getCode() + "]", e); + throw new ServiceRuntimeException("Error deleting taxRate [" + id + "] for store [" + store.getCode() + "]", e); + } + + } + + @Override + public ReadableTaxRate taxRate(Long id, MerchantStore store, Language language) { + + TaxRate model = taxRateById(id, store, language); + return readableTaxRateMapper.convert(model, store, language); + } + + @Override + public Entity createTaxRate(PersistableTaxRate taxRate, MerchantStore store, Language language) { + + Validate.notNull(taxRate,"TaxRate cannot be null"); + Validate.notNull(taxRate.getCode(),"TaxRate code cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null"); + Validate.notNull(store.getCode(),"MerchantStore code cannot be null"); + + + + try { + + TaxRate model = taxRateService.getByCode(taxRate.getCode(), store); + if(model!=null) { + throw new OperationNotAllowedException("Tax rate [" + taxRate.getCode() + "] already exist for store [" + store.getCode() + "]"); + } + + + model = persistableTaxRateMapper.convert(taxRate, store, language); + + model = taxRateService.saveOrUpdate(model); + + Entity id = new Entity(); + id.setId(model.getId()); + return id; + } catch (ServiceException e) { + LOGGER.error("Error while saving taxRate [" + taxRate.getCode() + "] for store [" + store.getCode() + "]", e); + throw new ServiceRuntimeException("Error while saving taxRate [" + taxRate.getCode() + "] for store [" + store.getCode() + "]", e); + } + + + } + + @Override + public void updateTaxRate(Long id, PersistableTaxRate taxRate, MerchantStore store, Language language) { + + Validate.notNull(taxRate,"TaxRate cannot be null"); + Validate.notNull(id,"TaxRate id cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null"); + Validate.notNull(store.getCode(),"MerchantStore code cannot be null"); + + TaxRate model = taxRateById(id, store, language); + + model = persistableTaxRateMapper.merge(taxRate, model, store, language); + + try { + model = taxRateService.saveOrUpdate(model); + + } catch (ServiceException e) { + LOGGER.error("Error while saving taxRate [" + taxRate.getCode() + "] for store [" + store.getCode() + "]", e); + throw new ServiceRuntimeException("Error while saving taxRate [" + taxRate.getCode() + "] for store [" + store.getCode() + "]", e); + } + + + } + + @Override + public boolean existsTaxRate(String code, MerchantStore store, Language language) { + + Validate.notNull(code,"TaxRate code cannot be null"); + Validate.notNull(store,"MerchantStore cannot be null"); + Validate.notNull(store.getCode(),"MerchantStore code cannot be null"); + + TaxRate rate = taxRateByCode(code, store, language); + if(rate == null) { + return false; + } + return true; + } + + @Override + public ReadableEntityList taxRates(MerchantStore store, Language language) { + + Validate.notNull(store,"MerchantStore cannot be null"); + Validate.notNull(store.getCode(),"MerchantStore code cannot be null"); + + try { + List rates = taxRateService.listByStore(store, language); + List readableRates = rates.stream().map(r -> readableTaxRateMapper.convert(r, store, language)).collect(Collectors.toList()); + + ReadableEntityList returnRates = new ReadableEntityList(); + returnRates.setItems(readableRates); + returnRates.setTotalPages(1); + returnRates.setNumber(readableRates.size()); + returnRates.setRecordsTotal(readableRates.size()); + + return returnRates; + } catch (ServiceException e) { + LOGGER.error("Error while getting taxRates for store [" + store.getCode() + "]", e); + throw new ServiceRuntimeException("Error while getting taxRates for store [" + store.getCode() + "]", e); + } + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/facade/user/UserFacadeImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/user/UserFacadeImpl.java new file mode 100755 index 0000000000..92a67643f6 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/facade/user/UserFacadeImpl.java @@ -0,0 +1,930 @@ +package com.salesmanager.shop.store.facade.user; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +import javax.inject.Inject; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.domain.Page; +import org.springframework.scheduling.annotation.Async; +import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import com.salesmanager.core.business.exception.ConversionException; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.modules.email.Email; +import com.salesmanager.core.business.services.merchant.MerchantStoreService; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.business.services.system.EmailService; +import com.salesmanager.core.business.services.user.PermissionService; +import com.salesmanager.core.business.services.user.UserService; +import com.salesmanager.core.model.common.CredentialsReset; +import com.salesmanager.core.model.common.Criteria; +import com.salesmanager.core.model.common.GenericEntityList; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.model.user.Permission; +import com.salesmanager.core.model.user.User; +import com.salesmanager.core.model.user.UserCriteria; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.constants.EmailConstants; +import com.salesmanager.shop.model.security.PersistableGroup; +import com.salesmanager.shop.model.security.ReadableGroup; +import com.salesmanager.shop.model.security.ReadablePermission; +import com.salesmanager.shop.model.user.PersistableUser; +import com.salesmanager.shop.model.user.ReadableUser; +import com.salesmanager.shop.model.user.ReadableUserList; +import com.salesmanager.shop.model.user.UserPassword; +import com.salesmanager.shop.populator.user.PersistableUserPopulator; +import com.salesmanager.shop.populator.user.ReadableUserPopulator; +import com.salesmanager.shop.store.api.exception.ConversionRuntimeException; +import com.salesmanager.shop.store.api.exception.GenericRuntimeException; +import com.salesmanager.shop.store.api.exception.OperationNotAllowedException; +import com.salesmanager.shop.store.api.exception.ResourceNotFoundException; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.api.exception.UnauthorizedException; +import com.salesmanager.shop.store.controller.security.facade.SecurityFacade; +import com.salesmanager.shop.store.controller.user.facade.UserFacade; +import com.salesmanager.shop.utils.DateUtil; +import com.salesmanager.shop.utils.EmailUtils; +import com.salesmanager.shop.utils.FilePathUtils; +import com.salesmanager.shop.utils.ImageFilePath; +import com.salesmanager.shop.utils.LabelUtils; + +@Service("userFacade") +public class UserFacadeImpl implements UserFacade { + + private static final String PRIVATE_PATH = "/private/"; + + private static final String resetUserLink = "user/%s/reset/%s"; // front + + private static final String ACCOUNT_PASSWORD_RESET_TPL = "email_template_password_reset_request_user.ftl"; + + private static final String RESET_PASSWORD_LINK = "RESET_PASSWORD_LINK"; + + private static final String RESET_PASSWORD_TEXT = "RESET_PASSWORD_TEXT"; + + @Inject + private MerchantStoreService merchantStoreService; + + @Inject + private UserService userService; + + @Inject + private PermissionService permissionService; + + @Inject + private LanguageService languageService; + + @Inject + private PersistableUserPopulator persistableUserPopulator; + + @Inject + private SecurityFacade securityFacade; + + @Autowired + private FilePathUtils filePathUtils; + + @Autowired + private LanguageService lamguageService; + + @Autowired + private EmailUtils emailUtils; + + @Autowired + private EmailService emailService; + + @Autowired + @Qualifier("img") + private ImageFilePath imageUtils; + + @Inject + private LabelUtils messages; + + @Inject + private PasswordEncoder passwordEncoder; + + private static final Logger LOGGER = LoggerFactory.getLogger(UserFacadeImpl.class); + + @Override + public ReadableUser findByUserName(String userName, String storeCode, Language lang) { + ReadableUser user = findByUserName(userName, lang); + if (user == null) { + throw new ResourceNotFoundException("User [" + userName + "] not found"); + } + + return user; + + } + + private ReadableUser findByUserName(String userName, Language lang) { + User user = getByUserName(userName); + if (user == null) { + throw new ResourceNotFoundException("User [" + userName + "] not found"); + } + return convertUserToReadableUser(lang, user); + } + + private ReadableUser convertUserToReadableUser(Language lang, User user) { + ReadableUserPopulator populator = new ReadableUserPopulator(); + try { + ReadableUser readableUser = new ReadableUser(); + readableUser = populator.populate(user, readableUser, user.getMerchantStore(), lang); + + List groupIds = readableUser.getGroups().stream().map(ReadableGroup::getId).map(Long::intValue) + .collect(Collectors.toList()); + List permissions = findPermissionsByGroups(groupIds); + readableUser.setPermissions(permissions); + + return readableUser; + } catch (ConversionException e) { + throw new ConversionRuntimeException(e); + } + } + + private User converPersistabletUserToUser(MerchantStore store, Language lang, User userModel, + PersistableUser user) { + try { + return persistableUserPopulator.populate(user, userModel, store, lang); + } catch (ConversionException e) { + throw new ConversionRuntimeException(e); + } + } + + private User getByUserName(String userName) { + try { + return userService.getByUserName(userName); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + } + + private User getByUserName(String userName, String storeCode) { + try { + return userService.getByUserName(userName, storeCode); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + } + + private User getByUserId(Long id, String storeCode) { + try { + return userService.findByStore(id, storeCode); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + } + + private User getByUserId(Long id) { + try { + return userService.getById(id); + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + } + + @Override + public List findPermissionsByGroups(List ids) { + return getPermissionsByIds(ids).stream().map(permission -> convertPermissionToReadablePermission(permission)) + .collect(Collectors.toList()); + } + + private ReadablePermission convertPermissionToReadablePermission(Permission permission) { + ReadablePermission readablePermission = new ReadablePermission(); + readablePermission.setId(permission.getId()); + readablePermission.setName(permission.getPermissionName()); + return readablePermission; + } + + private List getPermissionsByIds(List ids) { + try { + return permissionService.getPermissions(ids); + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + } + + @Override + public boolean authorizedStore(String userName, String merchantStoreCode) { + + try { + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + Set roles = authentication.getAuthorities().stream().map(r -> r.getAuthority()) + .collect(Collectors.toSet()); + + ReadableUser readableUser = findByUserName(userName, languageService.defaultLanguage()); + + // unless superadmin + for (ReadableGroup group : readableUser.getGroups()) { + if (Constants.GROUP_SUPERADMIN.equals(group.getName())) { + return true; + } + } + + boolean authorized = false; + User user = userService.findByStore(readableUser.getId(), merchantStoreCode); + if (user != null) { + authorized = true; + } else { + user = userService.getByUserName(userName); + } + + if (user != null && !authorized) { + + // get parent + MerchantStore store = merchantStoreService.getParent(merchantStoreCode); + + // user can be in parent + MerchantStore st = user.getMerchantStore(); + if (store != null && st.getCode().equals(store.getCode())) { + authorized = true; + } + } + + return authorized; + } catch (Exception e) { + throw new ServiceRuntimeException("Cannot authorize user " + userName + " for store " + merchantStoreCode, + e.getMessage()); + } + } + + @Override + public void authorizedGroup(String userName, List groupName) { + + ReadableUser readableUser = findByUserName(userName, languageService.defaultLanguage()); + + // unless superadmin + for (ReadableGroup group : readableUser.getGroups()) { + if (groupName.contains(group.getName())) { + return; + } + } + + throw new UnauthorizedException("User " + userName + " not authorized"); + + } + + @Override + public String authenticatedUser() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + if (authentication == null) { + throw new UnauthorizedException("User Not authorized"); + } + + if (!(authentication instanceof AnonymousAuthenticationToken)) { + String currentUserName = authentication.getName(); + return currentUserName; + } + return null; + } + + @Override + public ReadableUser create(PersistableUser user, MerchantStore store) { + + Validate.notNull(store, "MerchantStore must not be null"); + Validate.notNull(user, "User must not be null"); + Validate.notNull(user.getUserName(), "Username must not be null"); + + try { + + // check if user exists + User tempUser = userService.getByUserName(user.getUserName(), store.getCode()); + if (tempUser != null) { + throw new ServiceRuntimeException( + "User [" + user.getUserName() + "] already exists for store [" + store.getCode() + "]"); + } + + /** + * validate password + */ + if (!securityFacade.matchRawPasswords(user.getPassword(), user.getRepeatPassword())) { + throw new ServiceRuntimeException("Passwords dos not match, make sure password and repeat password are equals"); + } + + /** + * Validate new password + */ + if (!securityFacade.validateUserPassword(user.getPassword())) { + throw new ServiceRuntimeException("New password does not apply to format policy"); + } + + String newPasswordEncoded = securityFacade.encodePassword(user.getPassword()); + + User userModel = new User(); + userModel = converPersistabletUserToUser(store, languageService.defaultLanguage(), userModel, user); + if (CollectionUtils.isEmpty(userModel.getGroups())) { + throw new ServiceRuntimeException("No valid group groups associated with user " + user.getUserName()); + } + userModel.setAdminPassword(newPasswordEncoded); + userService.saveOrUpdate(userModel); + // now build returned object + User createdUser = userService.getById(userModel.getId()); + return convertUserToReadableUser(createdUser.getDefaultLanguage(), createdUser); + } catch (ServiceException e) { + throw new ServiceRuntimeException( + "Cannot create user " + user.getUserName() + " for store " + store.getCode(), e); + } + } + + @Override + public ReadableUserList getByCriteria(Language language, String drawParam, Criteria criteria) { + try { + ReadableUserList readableUserList = new ReadableUserList(); + GenericEntityList userList = userService.listByCriteria(criteria); + for (User user : userList.getList()) { + ReadableUser readableUser = this.convertUserToReadableUser(language, user); + readableUserList.getData().add(readableUser); + } + readableUserList.setRecordsTotal(userList.getTotalCount()); + readableUserList.setNumber(userList.getList().size()); + readableUserList.setTotalPages(userList.getTotalPages()); + // readableUserList.setTotalPages(readableUserList.getData().size()); + readableUserList.setRecordsFiltered(Math.toIntExact(userList.getTotalCount())); + + return readableUserList; + } catch (ServiceException e) { + throw new ServiceRuntimeException("Cannot get users by criteria user", e); + } + } + + @Override + public void delete(Long id, String merchant) { + Validate.notNull(id, "User id cannot be null"); + + try { + User user = userService.findByStore(id, merchant); + if (user == null) { + throw new ServiceRuntimeException("Cannot find user [" + id + "]"); + } + + // cannot delete superadmin + if (user.getGroups().contains(Constants.GROUP_SUPERADMIN)) { + throw new ServiceRuntimeException("Cannot delete superadmin user [" + id + "]"); + } + + userService.delete(user); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Cannot find user [" + id + "]", e); + } + + } + + @Override + public ReadableUser update(Long id, String authenticatedUser, MerchantStore store, PersistableUser user) { + Validate.notNull(user, "User cannot be null"); + Validate.notNull(store, "store cannot be null"); + + try { + User userModel = userService.getById(id); + if (userModel == null) { + throw new ServiceRuntimeException("Cannot find user [" + user.getUserName() + "]"); + } + if (userModel.getId().longValue() != id.longValue()) { + throw new ServiceRuntimeException( + "Cannot find user [" + user.getUserName() + "] id or name does not match"); + } + User auth = userService.getByUserName(authenticatedUser); + if (auth == null) { + throw new ServiceRuntimeException("Cannot find user [" + authenticatedUser + "]"); + } + User adminName = getByUserName(user.getUserName()); + if (adminName != null) { + if (adminName.getId().longValue() != userModel.getId().longValue()) { + throw new ServiceRuntimeException( + "User id [" + userModel.getId() + "] does not match [" + user.getUserName() + "]"); + } + } + boolean isActive = userModel.isActive(); + List originalGroups = userModel.getGroups(); + Group superadmin = originalGroups.stream() + .filter(group -> Constants.GROUP_SUPERADMIN.equals(group.getGroupName())).findAny().orElse(null); + + // changing store ? + /** + * Can't change self store Only admin and superadmin can change + * another user store + */ + + // i'm i editing my own profile ? + if (authenticatedUser.equals(adminName)) { + + if (!userModel.getMerchantStore().getCode().equals(store.getCode())) { + throw new OperationNotAllowedException("User [" + adminName + "] cannot change owning store"); + } + + } else { + // i am an admin or super admin + Group adminOrSuperadmin = originalGroups.stream() + .filter(group -> (Constants.GROUP_SUPERADMIN.equals(group.getGroupName()) + || Constants.ADMIN_USER.equals(group.getGroupName()) + || Constants.ADMIN_STORE.equals(group.getGroupName()))) + .findAny().orElse(null); + + if (!userModel.getMerchantStore().getCode().equals(store.getCode()) && adminOrSuperadmin == null) { + throw new OperationNotAllowedException("User [" + adminName + "] cannot change owning store"); + } + + } + + userModel = converPersistabletUserToUser(store, languageService.defaultLanguage(), userModel, user); + + // if superadmin set original permissions, prevent removing super + // admin + if (superadmin != null) { + userModel.setGroups(originalGroups); + } + + Group adminGroup = auth.getGroups().stream() + .filter((group) -> Constants.GROUP_SUPERADMIN.equals(group.getGroupName()) + || Constants.GROUP_SUPERADMIN.equals(group.getGroupName())) + .findAny().orElse(null); + + if (adminGroup == null) { + userModel.setGroups(originalGroups); + userModel.setActive(isActive); + } + + user.setPassword(userModel.getAdminPassword()); + userService.update(userModel); + return this.convertUserToReadableUser(languageService.defaultLanguage(), userModel); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Cannot update user [" + user.getUserName() + "]", e); + } + + } + + @Override + public void changePassword(Long userId, String authenticatedUser, UserPassword changePassword) { + + Validate.notNull(changePassword, "Change password request must not be null"); + Validate.notNull(changePassword.getPassword(), "Original password request must not be null"); + Validate.notNull(changePassword.getChangePassword(), "New password request must not be null"); + + /** + * Only admin and superadmin can change other user password + */ + User auth = null; + try { + auth = userService.getByUserName(authenticatedUser); + + if (auth == null) { + throw new ServiceRuntimeException("Cannot find user [" + authenticatedUser + "]"); + } + + User userModel = userService.getById(userId); + if (userModel == null) { + throw new ServiceRuntimeException("Cannot find user [" + userId + "]"); + } + + /** + * need to validate if actual password match + */ + + if (!securityFacade.matchPassword(userModel.getAdminPassword(), changePassword.getPassword())) { + throw new ServiceRuntimeException("Actual password does not match for user [" + userId + "]"); + } + + /** + * Validate new password + */ + if (!securityFacade.validateUserPassword(changePassword.getChangePassword())) { + throw new ServiceRuntimeException("New password does not apply to format policy"); + } + + String newPasswordEncoded = securityFacade.encodePassword(changePassword.getChangePassword()); + userModel.setAdminPassword(newPasswordEncoded); + + userService.update(userModel); + + } catch (ServiceException e) { + LOGGER.error("Error updating password"); + throw new ServiceRuntimeException(e); + } + + } + + @Override + public ReadableUserList listByCriteria(UserCriteria criteria, int page, int count, Language language) { + try { + ReadableUserList readableUserList = new ReadableUserList(); + // filtering by userName is not in this implementation + + Page userList = null; + + Optional storeCode = Optional.ofNullable(criteria.getStoreCode()); + if (storeCode.isPresent()) { + // get store + MerchantStore store = merchantStoreService.getByCode(storeCode.get()); + if (store != null && (store.isRetailer() != null)) { + if (store.isRetailer().booleanValue()) { + // get group stores + List stores = merchantStoreService.findAllStoreNames(store.getCode()); + List intList = stores.stream().map(s -> s.getId()).collect(Collectors.toList()); + criteria.setStoreIds(intList); + // search over store list + criteria.setStoreCode(null); + } + } + } + + userList = userService.listByCriteria(criteria, page, count); + List readableUsers = new ArrayList(); + if (userList != null) { + readableUsers = userList.getContent().stream().map(user -> convertUserToReadableUser(language, user)) + .collect(Collectors.toList()); + + readableUserList.setRecordsTotal(userList.getTotalElements()); + readableUserList.setTotalPages(userList.getTotalPages()); + readableUserList.setNumber(userList.getSize()); + readableUserList.setRecordsFiltered(userList.getSize()); + } + + readableUserList.setData(readableUsers); + + /* + * System.out.println(userList.getNumber()); + * System.out.println(userList.getNumberOfElements()); + * System.out.println(userList.getSize()); + * System.out.println(userList.getTotalElements()); + * System.out.println(userList.getTotalPages()); + */ + + return readableUserList; + } catch (ServiceException e) { + throw new ServiceRuntimeException("Cannot get users by criteria user", e); + } + } + + @Override + public void authorizedGroups(String authenticatedUser, PersistableUser user) { + Validate.notNull(authenticatedUser, "Required authenticated user"); + Validate.notNull(user, "Required persistable user"); + + try { + User currentUser = userService.getByUserName(authenticatedUser); + + boolean isSuperAdmin = false; + + for (Group g : currentUser.getGroups()) { + if (g.getGroupName().equals("SUPERADMIN")) { + isSuperAdmin = true; + break; + } + + } + + for (PersistableGroup g : user.getGroups()) { + if (g.getName().equals("SUPERADMIN")) { + if (!isSuperAdmin) { + throw new UnauthorizedException("Superadmin group not allowed"); + } + } + } + + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while looking for authorization", e); + } + + } + + @Override + public boolean userInRoles(String userName, List groupNames) { + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + List roles = authentication.getAuthorities().stream().filter(x -> groupNames.contains(x.getAuthority())) + .map(r -> r.getAuthority()).collect(Collectors.toList()); + + return roles.size() > 0; + + } + + @Override + public void updateEnabled(MerchantStore store, PersistableUser user) { + Validate.notNull(user, "User cannot be null"); + Validate.notNull(store, "MerchantStore cannot be null"); + Validate.notNull(user.getId(), "User.id cannot be null"); + + try { + User modelUser = userService.findByStore(user.getId(), store.getCode()); + + if (modelUser == null) { + throw new ResourceNotFoundException( + "User with id [" + user.getId() + "] not found for store [" + store.getCode() + "]"); + } + + modelUser.setActive(user.isActive()); + userService.saveOrUpdate(modelUser); + + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while updating user enable flag", e); + } + + } + + @Override + public boolean authorizeStore(MerchantStore store, String path) { + + if(store == null) { + throw new ResourceNotFoundException("MerchantStore is not found"); + } + + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + + if (!StringUtils.isBlank(path) && path.contains(PRIVATE_PATH)) { + + Validate.notNull(authentication, "Don't call ths method if a user is not authenticated"); + + try { + + + String currentPrincipalName = authentication.getName(); + + LOGGER.info("Principal " + currentPrincipalName); + + ReadableUser readableUser = findByUserName(currentPrincipalName, languageService.defaultLanguage()); + //ReadableUser readableUser = findByUserName(currentPrincipalName, store.getCode(), store.getDefaultLanguage()); + if (readableUser == null) { + return false; + } + + // current user match; + String merchant = readableUser.getMerchant(); + + //user store is store request param + if (store.getCode().equalsIgnoreCase(merchant)) { + return true; + } + + //Set roles = authentication.getAuthorities().stream().map(r -> r.getAuthority()) + // .collect(Collectors.toSet()); + + // is superadmin + for (ReadableGroup group : readableUser.getGroups()) { + if (Constants.GROUP_SUPERADMIN.equals(group.getName())) { + return true; + } + } + + boolean authorized = false; + + // user store can be parent and requested store is child + // get parent + // TODO CACHE + MerchantStore parent = null; + + if(store.getParent()!=null) { + parent=merchantStoreService.getParent(merchant); + } + + // user can be in parent + if (parent != null && parent.getCode().equals(store.getCode())) { + authorized = true; + } + + // else false + return authorized; + } catch (Exception e) { + throw new UnauthorizedException("Cannot authorize user " + authentication.getPrincipal().toString() + + " for store " + store.getCode(), e.getMessage()); + } + + } + + return true; + } + + @Override + public ReadableUser findById(Long id, MerchantStore store, Language lang) { + Validate.notNull(store, "MerchantStore cannot be null"); + + User user = userService.getById(id, store); + if (user == null) { + throw new ResourceNotFoundException("User [" + id + "] not found"); + } + + return convertUserToReadableUser(lang, user); + + } + + @Override + public ReadableUser findByUserName(String userName) { + Validate.notNull(userName, "userName cannot be null"); + User user; + try { + user = userService.getByUserName(userName); + if (user == null) { + throw new ResourceNotFoundException("User [" + userName + "] not found"); + } + + return this.convertUserToReadableUser(user.getDefaultLanguage(), user); + + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while getting user [" + userName + "]", e); + } + + } + + @Override + public void sendResetPasswordEmail(ReadableUser user, MerchantStore store, Language language) { + Validate.notNull(user, "ReadableUser is required"); + Validate.notNull(store, "MerchantStore is required"); + Validate.notNull(language, "Language is required"); + + // user already exist ? + + /** + * User sends username (unique in the system) + * + * UserNameEntity will be the following { userName: "test@test.com" } + * + * The system retrieves user using userName (username is unique) if user + * exists, system sends an email with reset password link + * + * How to retrieve a User from userName + * + * userFacade.findByUserName + * + * How to send an email + * + * + * How to generate a token + * + * Generate random token + * + * Calculate token expiration date + * + * Now + 48 hours + * + * How to update User in the database with token + * + * user.setPasswordToken + * + * Needs to use UserFacade to save to the database + * + * All of this done in the facade + */ + + } + + @Override + public void requestPasswordReset(String userName, String userContextPath, MerchantStore store, Language language) { + + Validate.notNull(userName, "Username cannot be empty"); + Validate.notNull(userContextPath, "Return url cannot be empty"); + + try { + // get user by user name + User user = userService.getByUserName(userName, store.getCode()); + + if (user == null) { + throw new ResourceNotFoundException( + "User [" + userName + "] not found for store [" + store.getCode() + "]"); + } + + // generates unique token + String token = UUID.randomUUID().toString(); + + Date expiry = DateUtil.addDaysToCurrentDate(2); + + CredentialsReset credsRequest = new CredentialsReset(); + credsRequest.setCredentialsRequest(token); + credsRequest.setCredentialsRequestExpiry(expiry); + user.setCredentialsResetRequest(credsRequest); + + userService.saveOrUpdate(user); + + // reset password link + // this will build http | https ://domain/contextPath + String baseUrl = userContextPath; + if(!filePathUtils.isValidURL(baseUrl)) { + throw new ServiceRuntimeException("Request url [" + baseUrl + "] is invalid"); + } + + // need to add link to controller receiving user reset password + // request + String customerResetLink = new StringBuilder().append(baseUrl) + .append(Constants.SLASH) + .append(String.format(resetUserLink, store.getCode(), token)).toString(); + + resetPasswordRequest(user, customerResetLink, store, lamguageService.toLocale(language, store)); + + } catch (Exception e) { + throw new ServiceRuntimeException("Error while executing resetPassword request", e); + } + + } + + @Override + public void verifyPasswordRequestToken(String token, String store) { + Validate.notNull(token, "ResetPassword token cannot be null"); + Validate.notNull(store, "Store code cannot be null"); + + verifyUserLink(token, store); + return; + } + + @Override + public void resetPassword(String password, String token, String store) { + Validate.notNull(token, "ResetPassword token cannot be null"); + Validate.notNull(store, "Store code cannot be null"); + Validate.notNull(password, "New password cannot be null"); + + User user = verifyUserLink(token, store);// reverify + user.setAdminPassword(passwordEncoder.encode(password)); + + try { + userService.save(user); + } catch (ServiceException e) { + throw new ServiceRuntimeException("Error while saving user",e); + } + + } + + private User verifyUserLink(String token, String store) { + + User user = null; + try { + user = userService.getByPasswordResetToken(store, token); + if (user == null) { + throw new ResourceNotFoundException( + "Customer not fount for store [" + store + "] and token [" + token + "]"); + } + + } catch (Exception e) { + throw new ServiceRuntimeException("Cannot verify customer token", e); + } + + Date tokenExpiry = user.getCredentialsResetRequest().getCredentialsRequestExpiry(); + + if (tokenExpiry == null) { + throw new GenericRuntimeException("No expiry date configured for token [" + token + "]"); + } + + if (!DateUtil.dateBeforeEqualsDate(new Date(), tokenExpiry)) { + throw new GenericRuntimeException("Ttoken [" + token + "] has expired"); + } + + return user; + + } + + + @Async + private void resetPasswordRequest(User user, String resetLink, MerchantStore store, Locale locale) + throws Exception { + try { + + + Map templateTokens = emailUtils.createEmailObjectsMap(imageUtils.getContextPath(), store, + messages, locale); + templateTokens.put(EmailConstants.LABEL_HI, messages.getMessage("label.generic.hi", locale)); + templateTokens.put(EmailConstants.EMAIL_USER_FIRSTNAME, user.getFirstName()); + templateTokens.put(RESET_PASSWORD_LINK, resetLink); + templateTokens.put(RESET_PASSWORD_TEXT, + messages.getMessage("email.reset.password.text", new String[] { store.getStorename() }, locale)); + templateTokens.put(EmailConstants.LABEL_LINK_TITLE, + messages.getMessage("email.link.reset.password.title", locale)); + templateTokens.put(EmailConstants.LABEL_LINK, messages.getMessage("email.link", locale)); + + + Email email = new Email(); + email.setFrom(store.getStorename()); + email.setFromEmail(store.getStoreEmailAddress()); + email.setSubject(messages.getMessage("email.link.reset.password.title", locale)); + email.setTo(user.getAdminEmail()); + email.setTemplateName(ACCOUNT_PASSWORD_RESET_TPL); + email.setTemplateTokens(templateTokens); + + emailService.sendHtmlEmail(store, email); + + } catch (Exception e) { + throw new Exception("Cannot send email to customer", e); + } + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/model/catalog/Attribute.java b/sm-shop/src/main/java/com/salesmanager/shop/store/model/catalog/Attribute.java new file mode 100755 index 0000000000..187f207064 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/model/catalog/Attribute.java @@ -0,0 +1,58 @@ +package com.salesmanager.shop.store.model.catalog; + +import java.io.Serializable; +import java.util.List; + +import com.salesmanager.shop.model.entity.ShopEntity; + + +public class Attribute extends ShopEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String name = null; + private String type = null; + private String code = null; + private List values = null; + private AttributeValue readOnlyValue = null; + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + + + + public void setValues(List values) { + this.values = values; + } + public List getValues() { + return values; + } + public void setCode(String code) { + this.code = code; + } + public String getCode() { + return code; + } + public void setReadOnlyValue(AttributeValue readOnlyValue) { + this.readOnlyValue = readOnlyValue; + } + public AttributeValue getReadOnlyValue() { + return readOnlyValue; + } + + + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/model/catalog/AttributeValue.java b/sm-shop/src/main/java/com/salesmanager/shop/store/model/catalog/AttributeValue.java new file mode 100755 index 0000000000..65cb13b892 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/model/catalog/AttributeValue.java @@ -0,0 +1,57 @@ +package com.salesmanager.shop.store.model.catalog; + +import java.io.Serializable; + +import com.salesmanager.shop.model.entity.ShopEntity; + +public class AttributeValue extends ShopEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + private String name = null; + private String description = null; + private boolean defaultAttribute; + private String image; + private String price; + private int sortOrder; + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public boolean isDefaultAttribute() { + return defaultAttribute; + } + public void setDefaultAttribute(boolean defaultAttribute) { + this.defaultAttribute = defaultAttribute; + } + public String getImage() { + return image; + } + public void setImage(String image) { + this.image = image; + } + public String getPrice() { + return price; + } + public void setPrice(String price) { + this.price = price; + } + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + public int getSortOrder() { + return sortOrder; + } + public void setSortOrder(int sortOrder) { + this.sortOrder = sortOrder; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/model/filter/QueryFilter.java b/sm-shop/src/main/java/com/salesmanager/shop/store/model/filter/QueryFilter.java new file mode 100755 index 0000000000..5a6589d8b8 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/model/filter/QueryFilter.java @@ -0,0 +1,39 @@ +package com.salesmanager.shop.store.model.filter; + +/** + * Used in Category and Search to filter display based on other + * entities such as Manufacturer + * @author Carl Samson + * + */ +public class QueryFilter { + + /** + * used when filtering on an entity code (example property) + */ + private String filterCode; + /** + * used when filtering on an entity id + */ + private Long filterId; + private QueryFilterType filterType; + public String getFilterCode() { + return filterCode; + } + public void setFilterCode(String filterCode) { + this.filterCode = filterCode; + } + public Long getFilterId() { + return filterId; + } + public void setFilterId(Long filterId) { + this.filterId = filterId; + } + public QueryFilterType getFilterType() { + return filterType; + } + public void setFilterType(QueryFilterType filterType) { + this.filterType = filterType; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/model/filter/QueryFilterType.java b/sm-shop/src/main/java/com/salesmanager/shop/store/model/filter/QueryFilterType.java new file mode 100755 index 0000000000..0d54e7aeb0 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/model/filter/QueryFilterType.java @@ -0,0 +1,7 @@ +package com.salesmanager.shop.store.model.filter; + +public enum QueryFilterType { + + BRAND + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/model/paging/PaginationData.java b/sm-shop/src/main/java/com/salesmanager/shop/store/model/paging/PaginationData.java new file mode 100755 index 0000000000..8f8ae7eb23 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/model/paging/PaginationData.java @@ -0,0 +1,143 @@ +/** + * + */ +package com.salesmanager.shop.store.model.paging; + +import java.io.Serializable; + +/** + * POJO representation of pagination + * @author Umesh Awasthi + * + */ +public class PaginationData implements Serializable +{ + + + private static final long serialVersionUID = 1L; + + /** The number of results per page.*/ + private int pageSize; + private int currentPage; + private int offset ; + private int totalCount; + private int totalPages; + private int countByPage; + + + public PaginationData(int pageSize,int currentPage) { + if (pageSize == 0) + throw new IllegalArgumentException("limit cannot be 0 for pagination."); + + + this.pageSize = pageSize; + this.currentPage=currentPage; + } + + + public int getPageSize() + { + return pageSize; + } + + + /** + * The current page number this pagination object represents + * + * @return the page number + */ + public int getPageNumber() { + if (offset < pageSize || pageSize == 0) + return 1; + + return (offset / pageSize) + 1; + } + + + /** + * The offset for this pagination object. The offset determines what index (0 index) to start retrieving results from. + * + * @return the offset + */ + public int getOffset() { + return (currentPage - 1) * pageSize + 1; + } + + + /** + * Creates a new pagination object representing the next page + * + * @return new pagination object with offset shifted by offset+limit + */ + public PaginationData getNext() + { + return new PaginationData( offset + pageSize, pageSize ); + } + + + /** + * Creates a new pagination object representing the previous page + * + * @return new pagination object with offset shifted by offset-limit + */ + public PaginationData getPrevious() { + if (pageSize >= offset) { + return new PaginationData(0, pageSize); + } else { + return new PaginationData(offset - pageSize, pageSize); + } + } + + + public int getCurrentPage() + { + return currentPage; + } + + + public void setCurrentPage( int currentPage ) + { + this.currentPage = currentPage; + } + + + public int getTotalCount() + { + return totalCount; + } + + + public void setTotalCount( int totalCount ) + { + this.totalCount = totalCount; + } + + + public int getTotalPages() + { + + Integer totalPages= Integer.valueOf((int) (Math.ceil(Integer.valueOf(totalCount).doubleValue() / pageSize))); + return totalPages; + } + + + public int getCountByPage() { + return countByPage; + } + + + public void setCountByPage(int countByPage) { + this.countByPage = countByPage; + } + + + public void setTotalPages(int totalPages) { + this.totalPages = totalPages; + } + + + + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/model/search/AutoCompleteRequest.java b/sm-shop/src/main/java/com/salesmanager/shop/store/model/search/AutoCompleteRequest.java new file mode 100755 index 0000000000..04b2f56ec4 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/model/search/AutoCompleteRequest.java @@ -0,0 +1,78 @@ +package com.salesmanager.shop.store.model.search; + +import org.json.simple.JSONObject; + +public class AutoCompleteRequest { + + private String merchantCode; + private String languageCode; + + + private final static String WILDCARD_QUERY = "wildcard"; + private final static String KEYWORD = "keyword"; + private final static String UNDERSCORE = "_"; + private final static String ALL = "*"; + private final static String TYPE = "type"; + private final static String ANALYZER = "analyzer"; + private final static String STD_ANALYZER = "standard"; + private final static String TYPE_PHRASE = "phrase_prefix"; + private final static String QUERY = "query"; + private final static String MATCH = "match"; + + public AutoCompleteRequest(String merchantCode, String languageCode) { + this.merchantCode = merchantCode; + this.languageCode = languageCode; + } + + @SuppressWarnings("unchecked") + @Deprecated + public String toJSONString(String query) { + + //{"size": 10,"query": {"match": {"keyword": {"query": "wat","operator":"and"}}}}"; + + + + JSONObject keyword = new JSONObject(); + JSONObject q = new JSONObject(); + JSONObject mq = new JSONObject(); + JSONObject match = new JSONObject(); + + q.put(QUERY, query); + q.put(ANALYZER, STD_ANALYZER); + + keyword.put(KEYWORD, q); + + match.put(MATCH, keyword); + + mq.put(QUERY, match); + return mq.toJSONString(); + } + + /** keyword_en_default **/ + public String getCollectionName() { + StringBuilder qBuilder = new StringBuilder(); + qBuilder.append(KEYWORD).append(UNDERSCORE).append(getLanguageCode()).append(UNDERSCORE) + .append(getMerchantCode()); + + return qBuilder.toString().toLowerCase(); + } + + + + public String getMerchantCode() { + return merchantCode; + } + + public void setMerchantCode(String merchantCode) { + this.merchantCode = merchantCode; + } + + public String getLanguageCode() { + return languageCode; + } + + public void setLanguageCode(String languageCode) { + this.languageCode = languageCode; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/AbstractCustomerServices.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/AbstractCustomerServices.java new file mode 100755 index 0000000000..ad6c97d9f1 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/AbstractCustomerServices.java @@ -0,0 +1,96 @@ +package com.salesmanager.shop.store.security; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.commons.collections4.CollectionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.dao.DataAccessException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.user.GroupService; +import com.salesmanager.core.business.services.user.PermissionService; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.model.user.Permission; +import com.salesmanager.shop.admin.security.SecurityDataAccessException; +import com.salesmanager.shop.constants.Constants; + +public abstract class AbstractCustomerServices implements UserDetailsService{ + + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractCustomerServices.class); + + protected CustomerService customerService; + protected PermissionService permissionService; + protected GroupService groupService; + + public final static String ROLE_PREFIX = "ROLE_";//Spring Security 4 + + public AbstractCustomerServices( + CustomerService customerService, + PermissionService permissionService, + GroupService groupService) { + + this.customerService = customerService; + this.permissionService = permissionService; + this.groupService = groupService; + } + + protected abstract UserDetails userDetails(String userName, Customer customer, Collection authorities); + + + public UserDetails loadUserByUsername(String userName) + throws UsernameNotFoundException, DataAccessException { + Customer user = null; + Collection authorities = new ArrayList(); + + try { + + LOGGER.debug("Loading user by user id: {}", userName); + + user = customerService.getByNick(userName); + + if(user==null) { + //return null; + throw new UsernameNotFoundException("User " + userName + " not found"); + } + + + + GrantedAuthority role = new SimpleGrantedAuthority(ROLE_PREFIX + Constants.PERMISSION_CUSTOMER_AUTHENTICATED);//required to login + authorities.add(role); + + List groupsId = new ArrayList(); + List groups = user.getGroups(); + for(Group group : groups) { + groupsId.add(group.getId()); + } + + + if(CollectionUtils.isNotEmpty(groupsId)) { + List permissions = permissionService.getPermissions(groupsId); + for(Permission permission : permissions) { + GrantedAuthority auth = new SimpleGrantedAuthority(permission.getPermissionName()); + authorities.add(auth); + } + } + + + } catch (ServiceException e) { + LOGGER.error("Exception while querrying customer",e); + throw new SecurityDataAccessException("Cannot authenticate customer",e); + } + + return userDetails(userName, user, authorities); + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/AuthenticationRequest.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/AuthenticationRequest.java new file mode 100755 index 0000000000..7d2b85ebb2 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/AuthenticationRequest.java @@ -0,0 +1,51 @@ +package com.salesmanager.shop.store.security; + +import java.io.Serializable; + +import javax.validation.constraints.NotEmpty; + +public class AuthenticationRequest implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Username and password must be used when using normal system authentication + * for a registered customer + */ + @NotEmpty(message="{NotEmpty.customer.userName}") + private String username; + @NotEmpty(message="{message.password.required}") + private String password; + + + + public AuthenticationRequest() { + super(); + } + + public AuthenticationRequest(String username, String password) { + this.setUsername(username); + this.setPassword(password); + } + + public String getUsername() { + return this.username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return this.password; + } + + public void setPassword(String password) { + this.password = password; + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/AuthenticationResponse.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/AuthenticationResponse.java new file mode 100755 index 0000000000..14dcbecafc --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/AuthenticationResponse.java @@ -0,0 +1,24 @@ +package com.salesmanager.shop.store.security; + +import java.io.Serializable; +import com.salesmanager.shop.model.entity.Entity; + +public class AuthenticationResponse extends Entity implements Serializable { + public AuthenticationResponse() {} + + /** + * + */ + private static final long serialVersionUID = 1L; + private String token; + + public AuthenticationResponse(Long userId, String token) { + this.token = token; + super.setId(userId); + } + + public String getToken() { + return token; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/AuthenticationTokenFilter.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/AuthenticationTokenFilter.java new file mode 100755 index 0000000000..075c670c69 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/AuthenticationTokenFilter.java @@ -0,0 +1,145 @@ +package com.salesmanager.shop.store.security; + +import java.io.IOException; +import java.util.Enumeration; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.inject.Inject; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.filter.OncePerRequestFilter; + +import com.salesmanager.core.model.common.UserContext; +import com.salesmanager.shop.store.security.common.CustomAuthenticationManager; +import com.salesmanager.shop.utils.GeoLocationUtils; + + +public class AuthenticationTokenFilter extends OncePerRequestFilter { + + + private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticationTokenFilter.class); + + + @Value("${authToken.header}") + private String tokenHeader; + + private final static String BEARER_TOKEN ="Bearer "; + + private final static String FACEBOOK_TOKEN ="FB "; + + //private final static String privateApiPatternString = "/api/v*/private"; + + //private final static Pattern pattern = Pattern.compile(privateApiPatternString); + + + + @Inject + private CustomAuthenticationManager jwtCustomCustomerAuthenticationManager; + + @Inject + private CustomAuthenticationManager jwtCustomAdminAuthenticationManager; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { + + + String origin = "*"; + if(!StringUtils.isBlank(request.getHeader("origin"))) { + origin = request.getHeader("origin"); + } + //in flight + response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH"); + response.setHeader("Access-Control-Allow-Origin", origin); + response.setHeader("Access-Control-Allow-Headers", "X-Auth-Token, Content-Type, Authorization, Cache-Control, X-Requested-With"); + response.setHeader("Access-Control-Allow-Credentials", "true"); + + try { + + String ipAddress = GeoLocationUtils.getClientIpAddress(request); + + UserContext userContext = UserContext.create(); + userContext.setIpAddress(ipAddress); + + } catch(Exception s) { + LOGGER.error("Error while getting ip address ", s); + } + + String requestUrl = request.getRequestURL().toString(); + + + if(requestUrl.contains("/api/v1/auth")) { + //setHeader(request,response); + final String requestHeader = request.getHeader(this.tokenHeader);//token + + try { + if (requestHeader != null && requestHeader.startsWith(BEARER_TOKEN)) {//Bearer + + jwtCustomCustomerAuthenticationManager.authenticateRequest(request, response); + + } else if(requestHeader != null && requestHeader.startsWith(FACEBOOK_TOKEN)) { + //Facebook + //facebookCustomerAuthenticationManager.authenticateRequest(request, response); + } else { + LOGGER.warn("couldn't find any authorization token, will ignore the header"); + } + + } catch(Exception e) { + throw new ServletException(e); + } + } + + + if(requestUrl.contains("/api/v1/private") || requestUrl.contains("/api/v2/private")) { + + //setHeader(request,response); + + Enumeration headers = request.getHeaderNames(); + //while(headers.hasMoreElements()) { + //LOGGER.debug(headers.nextElement()); + //} + + final String requestHeader = request.getHeader(this.tokenHeader);//token + + try { + if (requestHeader != null && requestHeader.startsWith(BEARER_TOKEN)) {//Bearer + + jwtCustomAdminAuthenticationManager.authenticateRequest(request, response); + + } else { + LOGGER.warn("couldn't find any authorization token, will ignore the header, might be a preflight check"); + } + + } catch(Exception e) { + throw new ServletException(e); + } + } + + chain.doFilter(request, response); + postFilter(request, response, chain); + } + + + private void postFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { + + try { + + UserContext userContext = UserContext.getCurrentInstance(); + if(userContext!=null) { + userContext.close(); + } + + } catch(Exception s) { + LOGGER.error("Error while getting ip address ", s); + } + + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/CustomerServicesImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/CustomerServicesImpl.java new file mode 100755 index 0000000000..2b3c35e109 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/CustomerServicesImpl.java @@ -0,0 +1,57 @@ +package com.salesmanager.shop.store.security; + +import java.util.Collection; +import javax.inject.Inject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Service; +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.user.GroupService; +import com.salesmanager.core.business.services.user.PermissionService; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.shop.store.security.user.CustomerDetails; + + +/** + * + * @author casams1 + * http://stackoverflow.com/questions/5105776/spring-security-with + * -custom-user-details + */ +@Service("customerDetailsService") +public class CustomerServicesImpl extends AbstractCustomerServices{ + + private static final Logger LOGGER = LoggerFactory.getLogger(CustomerServicesImpl.class); + + + private CustomerService customerService; + private PermissionService permissionService; + private GroupService groupService; + + @Inject + public CustomerServicesImpl(CustomerService customerService, PermissionService permissionService, GroupService groupService) { + super(customerService, permissionService, groupService); + this.customerService = customerService; + this.permissionService = permissionService; + this.groupService = groupService; + } + + @Override + protected UserDetails userDetails(String userName, Customer customer, Collection authorities) { + + CustomerDetails authUser = new CustomerDetails(userName, customer.getPassword(), true, true, + true, true, authorities); + + authUser.setEmail(customer.getEmailAddress()); + authUser.setId(customer.getId()); + + return authUser; + } + + + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/JWTTokenUtil.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/JWTTokenUtil.java new file mode 100755 index 0000000000..7770c250ba --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/JWTTokenUtil.java @@ -0,0 +1,193 @@ +package com.salesmanager.shop.store.security; + +import java.io.Serializable; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + +import com.salesmanager.shop.store.security.user.JWTUser; +import com.salesmanager.shop.utils.DateUtil; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + +/** + * Used for managing token based authentication for customer and user + * @author c.samson + * + */ +@Component +public class JWTTokenUtil implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + + static final int GRACE_PERIOD = 200; + + + + static final String CLAIM_KEY_USERNAME = "sub"; + static final String CLAIM_KEY_AUDIENCE = "aud"; + static final String CLAIM_KEY_CREATED = "iat"; + + static final String AUDIENCE_UNKNOWN = "unknown"; + static final String AUDIENCE_API = "api"; + static final String AUDIENCE_WEB = "web"; + static final String AUDIENCE_MOBILE = "mobile"; + static final String AUDIENCE_TABLET = "tablet"; + + + @Value("${jwt.secret}") + private String secret; + + @Value("${jwt.expiration}") + private Long expiration; + + public String getUsernameFromToken(String token) { + return getClaimFromToken(token, Claims::getSubject); + } + + public Date getIssuedAtDateFromToken(String token) { + return getClaimFromToken(token, Claims::getIssuedAt); + } + + public Date getExpirationDateFromToken(String token) { + return getClaimFromToken(token, Claims::getExpiration); + } + + public String getAudienceFromToken(String token) { + return getClaimFromToken(token, Claims::getAudience); + } + + public T getClaimFromToken(String token, Function claimsResolver) { + final Claims claims = getAllClaimsFromToken(token); + return claimsResolver.apply(claims); + } + + private Claims getAllClaimsFromToken(String token) { + return Jwts.parser() + .setSigningKey(secret) + .parseClaimsJws(token) + .getBody(); + } + + private Boolean isTokenExpired(String token) { + final Date expiration = getExpirationDateFromToken(token); + return expiration.before(DateUtil.getDate()); + } + + private Boolean isTokenExpiredWithGrace(String token) { + Date expiration = getExpirationDateFromToken(token); + expiration = addSeconds(expiration,GRACE_PERIOD); + return expiration.before(DateUtil.getDate()); + } + + private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset) { + return (lastPasswordReset != null && created.before(lastPasswordReset)); + } + + private Boolean isCreatedBeforeLastPasswordResetWithGrace(Date created, Date lastPasswordReset) { + return (lastPasswordReset != null && created.before(addSeconds(lastPasswordReset,GRACE_PERIOD))); + } + + private Date addSeconds(Date date, Integer seconds) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + cal.add(Calendar.SECOND, seconds); + return cal.getTime(); + } + + private String generateAudience() { + return AUDIENCE_API; + } + + private Boolean ignoreTokenExpiration(String token) { + String audience = getAudienceFromToken(token); + return (AUDIENCE_TABLET.equals(audience) || AUDIENCE_MOBILE.equals(audience)); + } + + public String generateToken(UserDetails userDetails) { + Map claims = new HashMap<>(); + return doGenerateToken(claims, userDetails.getUsername(), generateAudience()); + } + + private String doGenerateToken(Map claims, String subject, String audience) { + final Date createdDate = DateUtil.getDate(); + final Date expirationDate = calculateExpirationDate(createdDate); + + System.out.println("doGenerateToken " + createdDate); + + return Jwts.builder() + .setClaims(claims) + .setSubject(subject) + .setAudience(audience) + .setIssuedAt(createdDate) + .setExpiration(expirationDate) + .signWith(SignatureAlgorithm.HS512, secret) + .compact(); + } + + public Boolean canTokenBeRefreshedWithGrace(String token, Date lastPasswordReset) { + final Date created = getIssuedAtDateFromToken(token); + boolean t = isCreatedBeforeLastPasswordResetWithGrace(created, lastPasswordReset); + boolean u = isTokenExpiredWithGrace(token); + boolean v = ignoreTokenExpiration(token); + System.out.println(t + " " + u + " " + v); + System.out.println(!isCreatedBeforeLastPasswordResetWithGrace(created, lastPasswordReset) + && (!isTokenExpiredWithGrace(token) || ignoreTokenExpiration(token))); + //return !isCreatedBeforeLastPasswordResetWithGrace(created, lastPasswordReset) + // && (!isTokenExpired(token) || ignoreTokenExpiration(token)); + return true; + } + + public Boolean canTokenBeRefreshed(String token, Date lastPasswordReset) { + final Date created = getIssuedAtDateFromToken(token); + return !isCreatedBeforeLastPasswordReset(created, lastPasswordReset) + && (!isTokenExpired(token) || ignoreTokenExpiration(token)); + } + + public String refreshToken(String token) { + final Date createdDate = DateUtil.getDate(); + final Date expirationDate = calculateExpirationDate(createdDate); + + final Claims claims = getAllClaimsFromToken(token); + claims.setIssuedAt(createdDate); + claims.setExpiration(expirationDate); + + return Jwts.builder() + .setClaims(claims) + .signWith(SignatureAlgorithm.HS512, secret) + .compact(); + } + + public Boolean validateToken(String token, UserDetails userDetails) { + JWTUser user = (JWTUser) userDetails; + final String username = getUsernameFromToken(token); + final Date created = getIssuedAtDateFromToken(token); + //final Date expiration = getExpirationDateFromToken(token); + + boolean usernameEquals = username.equals(user.getUsername()); + boolean isTokenExpired = isTokenExpired(token); + boolean isTokenCreatedBeforeLastPasswordReset = isCreatedBeforeLastPasswordReset(created, user.getLastPasswordResetDate()); + + return ( + + usernameEquals && !isTokenExpired && !isTokenCreatedBeforeLastPasswordReset + ); + } + + private Date calculateExpirationDate(Date createdDate) { + return new Date(createdDate.getTime() + expiration * 1000); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/PasswordRequest.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/PasswordRequest.java new file mode 100644 index 0000000000..2c1f929caa --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/PasswordRequest.java @@ -0,0 +1,34 @@ +package com.salesmanager.shop.store.security; + +import javax.validation.constraints.NotEmpty; + +public class PasswordRequest extends AuthenticationRequest { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @NotEmpty(message = "{message.password.required}") + private String current; + + @NotEmpty(message = "{message.password.required}") + private String repeatPassword; + + public String getCurrent() { + return current; + } + + public void setCurrent(String current) { + this.current = current; + } + + public String getRepeatPassword() { + return repeatPassword; + } + + public void setRepeatPassword(String repeatPassword) { + this.repeatPassword = repeatPassword; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/ResetPasswordRequest.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/ResetPasswordRequest.java new file mode 100755 index 0000000000..e4f3daa918 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/ResetPasswordRequest.java @@ -0,0 +1,49 @@ +package com.salesmanager.shop.store.security; + +import java.io.Serializable; + +import javax.validation.constraints.NotEmpty; + +public class ResetPasswordRequest implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Username and password must be used when requesting password request + */ + @NotEmpty(message="{NotEmpty.customer.userName}") + private String username; + + + private String returnUrl; + + + + public ResetPasswordRequest() { + super(); + } + + public ResetPasswordRequest(String username) { + this.setUsername(username); + } + + public String getUsername() { + return this.username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getReturnUrl() { + return returnUrl; + } + + public void setReturnUrl(String returnUrl) { + this.returnUrl = returnUrl; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/RestAuthenticationEntryPoint.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/RestAuthenticationEntryPoint.java new file mode 100755 index 0000000000..40a664e490 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/RestAuthenticationEntryPoint.java @@ -0,0 +1,41 @@ +package com.salesmanager.shop.store.security; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.InitializingBean; +import org.springframework.core.Ordered; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +@Component("restAuthenticationEntryPoint") +public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint, InitializingBean, Ordered { + + private String realmName = "rest-realm"; + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, + AuthenticationException authException) throws IOException, ServletException { + + + response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized" ); + + } + + @Override + public int getOrder() { + return 1; + } + + @Override + public void afterPropertiesSet() throws Exception { + if ((realmName == null) || "".equals(realmName)) { + throw new IllegalArgumentException("realmName must be specified"); + } + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/ServicesAuthenticationEntryPoint.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/ServicesAuthenticationEntryPoint.java new file mode 100755 index 0000000000..bc77e3a0f8 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/ServicesAuthenticationEntryPoint.java @@ -0,0 +1,36 @@ +package com.salesmanager.shop.store.security; + +import org.springframework.beans.factory.InitializingBean; +import org.springframework.core.Ordered; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class ServicesAuthenticationEntryPoint implements AuthenticationEntryPoint, InitializingBean, Ordered { + + + private String realmName = "services-realm"; + + @Override + public void commence( HttpServletRequest request, HttpServletResponse response, + AuthenticationException authException ) throws IOException{ + response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized" ); + } + + @Override + public int getOrder() { + return 0; + } + + @Override + public void afterPropertiesSet() throws Exception { + if ((realmName == null) || "".equals(realmName)) { + throw new IllegalArgumentException("realmName must be specified"); + } + + } + +} \ No newline at end of file diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/ServicesAuthenticationSuccessHandler.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/ServicesAuthenticationSuccessHandler.java new file mode 100755 index 0000000000..100e8036e6 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/ServicesAuthenticationSuccessHandler.java @@ -0,0 +1,42 @@ +package com.salesmanager.shop.store.security; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; +import org.springframework.security.web.savedrequest.HttpSessionRequestCache; +import org.springframework.security.web.savedrequest.RequestCache; +import org.springframework.security.web.savedrequest.SavedRequest; +import org.springframework.util.StringUtils; + +public class ServicesAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { + + private RequestCache requestCache = new HttpSessionRequestCache(); + + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException { + SavedRequest savedRequest = requestCache.getRequest(request, response); + + if (savedRequest == null) { + clearAuthenticationAttributes(request); + return; + } + String targetUrlParam = getTargetUrlParameter(); + if (isAlwaysUseDefaultTargetUrl() || (targetUrlParam != null && StringUtils.hasText(request.getParameter(targetUrlParam)))) { + requestCache.removeRequest(request, response); + clearAuthenticationAttributes(request); + return; + } + + clearAuthenticationAttributes(request); + } + + public void setRequestCache(RequestCache requestCache) { + this.requestCache = requestCache; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/SocialCustomerServicesImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/SocialCustomerServicesImpl.java new file mode 100755 index 0000000000..58950fa5e9 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/SocialCustomerServicesImpl.java @@ -0,0 +1,28 @@ +package com.salesmanager.shop.store.security; + +import javax.inject.Inject; + +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + + +@Service("socialCustomerDetailsService") +public class SocialCustomerServicesImpl implements UserDetailsService{ + + @Inject + UserDetailsService customerDetailsService; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + //delegates to Customer fetch service + UserDetails userDetails = customerDetailsService.loadUserByUsername(username); + if (userDetails == null) { + return null; + } + + return userDetails; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/admin/AdminAccessDeniedHandler.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/admin/AdminAccessDeniedHandler.java new file mode 100755 index 0000000000..48d0487976 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/admin/AdminAccessDeniedHandler.java @@ -0,0 +1,33 @@ +package com.salesmanager.shop.store.security.admin; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; + +public class AdminAccessDeniedHandler implements AccessDeniedHandler { + + @Override + public void handle(HttpServletRequest request, + HttpServletResponse response, + AccessDeniedException accessDeniedException) throws IOException, + ServletException { + response.sendRedirect(request.getContextPath() + getAccessDeniedUrl()); + + } + + public String getAccessDeniedUrl() { + return accessDeniedUrl; + } + + public void setAccessDeniedUrl(String accessDeniedUrl) { + this.accessDeniedUrl = accessDeniedUrl; + } + + private String accessDeniedUrl = null; + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/admin/JWTAdminAuthenticationManager.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/admin/JWTAdminAuthenticationManager.java new file mode 100755 index 0000000000..90d7b06801 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/admin/JWTAdminAuthenticationManager.java @@ -0,0 +1,94 @@ +package com.salesmanager.shop.store.security.admin; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import com.salesmanager.shop.store.security.JWTTokenUtil; +import com.salesmanager.shop.store.security.common.CustomAuthenticationException; +import com.salesmanager.shop.store.security.common.CustomAuthenticationManager; +import static java.util.Optional.ofNullable; +import static org.apache.commons.lang3.StringUtils.removeStart; +import io.jsonwebtoken.ExpiredJwtException; + +@Component("jwtCustomAdminAuthenticationManager") +public class JWTAdminAuthenticationManager extends CustomAuthenticationManager { + + protected final Log logger = LogFactory.getLog(getClass()); + private static final String BEARER = "Bearer"; + + @Inject + private JWTTokenUtil jwtTokenUtil; + + @Inject + private UserDetailsService jwtAdminDetailsService; + + @Override + public Authentication attemptAuthentication(HttpServletRequest request, + HttpServletResponse response) throws AuthenticationException { + + final String requestHeader = request.getHeader(super.getTokenHeader());// token + String username = null; + final String authToken; + + authToken = ofNullable(requestHeader).map(value -> removeStart(value, BEARER)).map(String::trim) + .orElseThrow(() -> new CustomAuthenticationException("Missing Authentication Token")); + + try { + username = jwtTokenUtil.getUsernameFromToken(authToken); + } catch (IllegalArgumentException e) { + logger.error("an error occured during getting username from token", e); + } catch (ExpiredJwtException e) { + logger.warn("the token is expired and not valid anymore", e); + } + + + UsernamePasswordAuthenticationToken authentication = null; + + logger.info("checking authentication for user " + username); + if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { + + // It is not compelling necessary to load the use details from the database. You could also + // store the information + // in the token and read it from it. It's up to you ;) + UserDetails userDetails = this.jwtAdminDetailsService.loadUserByUsername(username); + + // For simple validation it is completely sufficient to just check the token integrity. You + // don't have to call + // the database compellingly. Again it's up to you ;) + if (userDetails != null && jwtTokenUtil.validateToken(authToken, userDetails)) { + authentication = new UsernamePasswordAuthenticationToken(userDetails, null, + userDetails.getAuthorities()); + authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + logger.info("authenticated user " + username + ", setting security context"); + // SecurityContextHolder.getContext().setAuthentication(authentication); + } + } + + return authentication; + } + + @Override + public void successfullAuthentication(HttpServletRequest request, HttpServletResponse response, + Authentication authentication) throws AuthenticationException { + // TODO Auto-generated method stub + + } + + @Override + public void unSuccessfullAuthentication(HttpServletRequest request, HttpServletResponse response) + throws AuthenticationException { + // TODO Auto-generated method stub + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/admin/JWTAdminAuthenticationProvider.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/admin/JWTAdminAuthenticationProvider.java new file mode 100755 index 0000000000..47f635083f --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/admin/JWTAdminAuthenticationProvider.java @@ -0,0 +1,71 @@ +package com.salesmanager.shop.store.security.admin; + +import javax.inject.Inject; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.password.PasswordEncoder; + + +/** + * Custom authautentication provider for admin api + * @author carlsamson + * + */ +public class JWTAdminAuthenticationProvider extends DaoAuthenticationProvider { + + @Autowired + private UserDetailsService jwtAdminDetailsService; + + @Inject + private PasswordEncoder passwordEncoder; + + public UserDetailsService getJwtAdminDetailsService() { + return jwtAdminDetailsService; + } + public void setJwtAdminDetailsService(UserDetailsService jwtAdminDetailsService) { + this.jwtAdminDetailsService = jwtAdminDetailsService; + } + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + UsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) authentication; + String name = auth.getName(); + Object credentials = auth.getCredentials(); + UserDetails user = jwtAdminDetailsService.loadUserByUsername(name); + if (user == null) { + throw new BadCredentialsException("Username/Password does not match for " + auth.getPrincipal()); + } + + String pass = credentials.toString(); + String usr = name; + + if(!passwordMatch(pass, usr)) { + throw new BadCredentialsException("Username/Password does not match for " + auth.getPrincipal()); + } + + + /** + * username password auth + */ + + + return new UsernamePasswordAuthenticationToken(user, credentials, user.getAuthorities()); + } + + + private boolean passwordMatch(String rawPassword, String user) { + return passwordEncoder.matches(rawPassword, user); + } + + @Override + public boolean supports(Class authentication) { + return true; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/admin/JWTAdminServicesImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/admin/JWTAdminServicesImpl.java new file mode 100755 index 0000000000..5e536b4446 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/admin/JWTAdminServicesImpl.java @@ -0,0 +1,114 @@ +package com.salesmanager.shop.store.security.admin; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; + +import javax.inject.Inject; + +import org.apache.commons.collections4.CollectionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.user.GroupService; +import com.salesmanager.core.business.services.user.PermissionService; +import com.salesmanager.core.business.services.user.UserService; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.model.user.Permission; +import com.salesmanager.core.model.user.User; +import com.salesmanager.shop.admin.security.SecurityDataAccessException; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.store.security.user.JWTUser; + + +@Service("jwtAdminDetailsService") +public class JWTAdminServicesImpl implements UserDetailsService{ + + private static final Logger LOGGER = LoggerFactory.getLogger(JWTAdminServicesImpl.class); + + + @Inject + private UserService userService; + @Inject + private PermissionService permissionService; + @Inject + private GroupService groupService; + + public final static String ROLE_PREFIX = "ROLE_";//Spring Security 4 + + + private UserDetails userDetails(String userName, User user, Collection authorities) { + + AuditSection section = null; + section = user.getAuditSection(); + Date lastModified = null; + //if(section != null) {//does not represent password change + // lastModified = section.getDateModified(); + //} + + return new JWTUser( + user.getId(), + userName, + user.getFirstName(), + user.getLastName(), + user.getAdminEmail(), + user.getAdminPassword(), + authorities, + true, + lastModified + ); + } + + @Override + public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException { + User user = null; + Collection authorities = new ArrayList(); + + try { + + LOGGER.debug("Loading user by user id: {}", userName); + + user = userService.getByUserName(userName); + + if(user==null) { + //return null; + throw new UsernameNotFoundException("User " + userName + " not found"); + } + + GrantedAuthority role = new SimpleGrantedAuthority(ROLE_PREFIX + Constants.PERMISSION_AUTHENTICATED);//required to login + authorities.add(role); + + List groupsId = new ArrayList(); + List groups = user.getGroups(); + for(Group group : groups) { + groupsId.add(group.getId()); + } + + + if(CollectionUtils.isNotEmpty(groupsId)) { + List permissions = permissionService.getPermissions(groupsId); + for(Permission permission : permissions) { + GrantedAuthority auth = new SimpleGrantedAuthority(permission.getPermissionName()); + authorities.add(auth); + } + } + + + } catch (ServiceException e) { + LOGGER.error("Exception while querrying customer",e); + throw new SecurityDataAccessException("Cannot authenticate customer",e); + } + + return userDetails(userName, user, authorities); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/common/CustomAuthenticationException.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/common/CustomAuthenticationException.java new file mode 100755 index 0000000000..aad1e047d0 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/common/CustomAuthenticationException.java @@ -0,0 +1,16 @@ +package com.salesmanager.shop.store.security.common; + +import org.springframework.security.core.AuthenticationException; + +public class CustomAuthenticationException extends AuthenticationException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public CustomAuthenticationException(String msg) { + super(msg); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/common/CustomAuthenticationManager.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/common/CustomAuthenticationManager.java new file mode 100755 index 0000000000..b0bab028d3 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/common/CustomAuthenticationManager.java @@ -0,0 +1,93 @@ +package com.salesmanager.shop.store.security.common; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.context.SecurityContextHolder; + +/** + * Abstract authentication manager to be used by various internal Authentication manager + * invoked from a SecurityFilter placed in the security filter chain of given http configuration. + * @author c.samson + * + */ +public abstract class CustomAuthenticationManager { + + protected final Log logger = LogFactory.getLog(getClass()); + + @Value("${authToken.header}") + private String tokenHeader; + + + public String getTokenHeader() { + return tokenHeader; + } + + public void setTokenHeader(String tokenHeader) { + this.tokenHeader = tokenHeader; + } + + public void authenticateRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { + + + if (logger.isDebugEnabled()) { + logger.debug("Processing authentication"); + } + + Authentication authResult = null; + + try { + authResult = this.attemptAuthentication(request, response); + if (authResult == null) { + // return immediately as subclass has indicated that it hasn't completed + // authentication + return; + } + } catch (AuthenticationException failed) { + // Authentication failed + unsuccess(request, response); + return; + } + + this.success(request, response, authResult); + + + } + + private void success(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws AuthenticationException { + + SecurityContextHolder.getContext().setAuthentication(authentication); + + if (logger.isDebugEnabled()) { + logger.debug("Authentication success"); + logger.debug("Updated SecurityContextHolder to containAuthentication"); + } + + successfullAuthentication(request, response, authentication); + } + + private void unsuccess(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { + + SecurityContextHolder.clearContext(); + + if (logger.isDebugEnabled()) { + logger.debug("Authentication request failed"); + logger.debug("Updated SecurityContextHolder to contain null Authentication"); + } + + unSuccessfullAuthentication(request, response); + } + + + public abstract Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, Exception; + + public abstract void successfullAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws AuthenticationException; + + public abstract void unSuccessfullAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException; + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/customer/JWTCustomerAuthenticationManager.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/customer/JWTCustomerAuthenticationManager.java new file mode 100755 index 0000000000..97a48d0966 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/customer/JWTCustomerAuthenticationManager.java @@ -0,0 +1,92 @@ +package com.salesmanager.shop.store.security.customer; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; + +import com.salesmanager.shop.store.security.JWTTokenUtil; +import com.salesmanager.shop.store.security.common.CustomAuthenticationException; +import com.salesmanager.shop.store.security.common.CustomAuthenticationManager; + +import io.jsonwebtoken.ExpiredJwtException; + +@Component("jwtCustomCustomerAuthenticationManager")//different than jwtCustomerAuthenticationManager +public class JWTCustomerAuthenticationManager extends CustomAuthenticationManager { + + protected final Log logger = LogFactory.getLog(getClass()); + + @Inject + private JWTTokenUtil jwtTokenUtil; + + @Inject + private UserDetailsService jwtCustomerDetailsService; + + @Override + public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) + throws AuthenticationException { + + final String requestHeader = request.getHeader(super.getTokenHeader());//token + String username = null; + String authToken = null; + if (requestHeader != null && requestHeader.startsWith("Bearer ")) {//Bearer + authToken = requestHeader.substring(7); + try { + username = jwtTokenUtil.getUsernameFromToken(authToken); + } catch (IllegalArgumentException e) { + logger.error("an error occured during getting username from token", e); + } catch (ExpiredJwtException e) { + logger.warn("the token is expired and not valid anymore", e); + } + } else { + throw new CustomAuthenticationException("No Bearer token found in the request"); + } + + UsernamePasswordAuthenticationToken authentication = null; + + + logger.info("checking authentication for user " + username); + if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { + + // It is not compelling necessary to load the use details from the database. You could also store the information + // in the token and read it from it. It's up to you ;) + UserDetails userDetails = this.jwtCustomerDetailsService.loadUserByUsername(username); + + // For simple validation it is completely sufficient to just check the token integrity. You don't have to call + // the database compellingly. Again it's up to you ;) + if (userDetails != null && jwtTokenUtil.validateToken(authToken, userDetails)) { + authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); + authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + logger.info("authenticated user " + username + ", setting security context"); + //SecurityContextHolder.getContext().setAuthentication(authentication); + } + } + + return authentication; + } + + @Override + public void successfullAuthentication(HttpServletRequest request, HttpServletResponse response, + Authentication authentication) throws AuthenticationException { + // TODO Auto-generated method stub + + } + + @Override + public void unSuccessfullAuthentication(HttpServletRequest request, HttpServletResponse response) + throws AuthenticationException { + // TODO Auto-generated method stub + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/customer/JWTCustomerAuthenticationProvider.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/customer/JWTCustomerAuthenticationProvider.java new file mode 100755 index 0000000000..432ab8b9a1 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/customer/JWTCustomerAuthenticationProvider.java @@ -0,0 +1,74 @@ +package com.salesmanager.shop.store.security.customer; + +import javax.inject.Inject; + +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.password.PasswordEncoder; + +/** + * Custom authautentication provider for customer api + * @author carlsamson + * + */ +public class JWTCustomerAuthenticationProvider extends DaoAuthenticationProvider { + + @Inject + private UserDetailsService jwtCustomerDetailsService; + + @Inject + private PasswordEncoder passwordEncoder; + + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + UsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) authentication; + String name = auth.getName(); + Object credentials = auth.getCredentials(); + UserDetails customer = jwtCustomerDetailsService.loadUserByUsername(name); + if (customer == null) { + throw new BadCredentialsException("Username/Password does not match for " + auth.getPrincipal()); + } + + String pass = credentials.toString(); + String usr = name; + + if(!passwordMatch(pass, usr)) { + throw new BadCredentialsException("Username/Password does not match for " + auth.getPrincipal()); + } + + + /** + * username password auth + */ + + + return new UsernamePasswordAuthenticationToken(customer, credentials, customer.getAuthorities()); + } + + + private boolean passwordMatch(String rawPassword, String user) { + return passwordEncoder.matches(rawPassword, user); + } + + @Override + public boolean supports(Class authentication) { + return true; + } + + + public UserDetailsService getJwtCustomerDetailsService() { + return jwtCustomerDetailsService; + } + + + public void setJwtCustomerDetailsService(UserDetailsService jwtCustomerDetailsService) { + this.jwtCustomerDetailsService = jwtCustomerDetailsService; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/customer/JWTCustomerServicesImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/customer/JWTCustomerServicesImpl.java new file mode 100755 index 0000000000..79636808a8 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/customer/JWTCustomerServicesImpl.java @@ -0,0 +1,56 @@ +package com.salesmanager.shop.store.security.customer; + +import java.util.Collection; +import java.util.Date; + +import javax.inject.Inject; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Service; + +import com.salesmanager.core.business.services.customer.CustomerService; +import com.salesmanager.core.business.services.user.GroupService; +import com.salesmanager.core.business.services.user.PermissionService; +import com.salesmanager.core.model.common.audit.AuditSection; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.shop.store.security.AbstractCustomerServices; +import com.salesmanager.shop.store.security.user.JWTUser; + + +@Service("jwtCustomerDetailsService") +public class JWTCustomerServicesImpl extends AbstractCustomerServices { + + + @Inject + public JWTCustomerServicesImpl(CustomerService customerService, PermissionService permissionService, GroupService groupService) { + super(customerService, permissionService, groupService); + this.customerService = customerService; + this.permissionService = permissionService; + this.groupService = groupService; + } + + @Override + protected UserDetails userDetails(String userName, Customer customer, Collection authorities) { + + AuditSection section = null; + section = customer.getAuditSection(); + Date lastModified = null; + //if(section != null) {//does not represent password change + // lastModified = section.getDateModified(); + //} + + return new JWTUser( + customer.getId(), + userName, + customer.getBilling().getFirstName(), + customer.getBilling().getLastName(), + customer.getEmailAddress(), + customer.getPassword(), + authorities, + true, + lastModified + ); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/services/CredentialsException.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/services/CredentialsException.java new file mode 100644 index 0000000000..26c5dbaffb --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/services/CredentialsException.java @@ -0,0 +1,18 @@ +package com.salesmanager.shop.store.security.services; + +public class CredentialsException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + public CredentialsException(String message) { + super(message); + } + + public CredentialsException(String message, Exception e) { + super(message, e); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/services/CredentialsService.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/services/CredentialsService.java new file mode 100644 index 0000000000..ee5bcf0298 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/services/CredentialsService.java @@ -0,0 +1,27 @@ +package com.salesmanager.shop.store.security.services; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +public interface CredentialsService { + + /** + * Password validation with specific rules + * @param password + * @param repeatPassword + * @param store + * @param language + * @throws CredentialsException + */ + void validateCredentials(String password, String repeatPassword, MerchantStore store, Language language) throws CredentialsException; + + /** + * Generates password based on specific rules + * @param store + * @param language + * @return + * @throws CredentialsException + */ + String generatePassword(MerchantStore store, Language language) throws CredentialsException; + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/services/CredentialsServiceImpl.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/services/CredentialsServiceImpl.java new file mode 100644 index 0000000000..0a06df61fc --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/services/CredentialsServiceImpl.java @@ -0,0 +1,58 @@ +package com.salesmanager.shop.store.security.services; + +import org.apache.commons.lang3.StringUtils; +import org.passay.CharacterRule; +import org.passay.EnglishCharacterData; +import org.passay.LengthRule; +import org.passay.PasswordData; +import org.passay.PasswordValidator; +import org.passay.RuleResult; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + +/** + * Internal credentials service + * @author carlsamson + * + */ +public class CredentialsServiceImpl implements CredentialsService { + + @Override + public void validateCredentials(String password, String repeatPassword, MerchantStore store, Language language) + throws CredentialsException { + + if(StringUtils.isBlank(password) || StringUtils.isBlank(repeatPassword) ) { + throw new CredentialsException("Empty password not supported"); + } + + /** + * validate - both password match + */ + if(!password.equals(repeatPassword)) { + throw new CredentialsException("Password don't match"); + } + + //create your own rules + PasswordValidator passwordValidator = new PasswordValidator( + new CharacterRule(EnglishCharacterData.Digit, 1),//at least 1 digit + new CharacterRule(EnglishCharacterData.Special, 1),// at least 1 special character + new LengthRule(8, 12)//8 to 12 characters + ); + + PasswordData passwordData = new PasswordData(password); + RuleResult result = passwordValidator.validate(passwordData); + + if(!result.isValid()){ + throw new CredentialsException("Password validation failed [" + passwordValidator.getMessages(result) + "]"); + } + + } + + @Override + public String generatePassword(MerchantStore store, Language language) throws CredentialsException { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/user/CustomerDetails.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/user/CustomerDetails.java new file mode 100755 index 0000000000..21dd1958f2 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/user/CustomerDetails.java @@ -0,0 +1,70 @@ +package com.salesmanager.shop.store.security.user; + +import java.util.Collection; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.User; + +public class CustomerDetails extends User { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private String email; + private Long id; + private String firstName; + private String lastName; + + public CustomerDetails( + String username, + String password, + boolean enabled, + boolean accountNonExpired, + boolean credentialsNonExpired, + boolean accountNonLocked, + Collection authorities) { + super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); + } + + public CustomerDetails( + String username, + String password, + Collection authorities) { + super(username, password, true, true, true, true, authorities); + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/store/security/user/JWTUser.java b/sm-shop/src/main/java/com/salesmanager/shop/store/security/user/JWTUser.java new file mode 100755 index 0000000000..eb1f7055de --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/store/security/user/JWTUser.java @@ -0,0 +1,109 @@ +package com.salesmanager.shop.store.security.user; + +import java.util.Collection; +import java.util.Date; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +public class JWTUser implements UserDetails { + + /** + * + */ + private static final long serialVersionUID = 1L; + private final Long id; + private final String username; + private final String firstname; + private final String lastname; + private final String password; + private final String email; + private final Collection authorities; + private final boolean enabled; + private final Date lastPasswordResetDate; + + public JWTUser( + Long id, + String username, + String firstname, + String lastname, + String email, + String password, Collection authorities, + boolean enabled, + Date lastPasswordResetDate + ) { + this.id = id; + this.username = username; + this.firstname = firstname; + this.lastname = lastname; + this.email = email; + this.password = password; + this.authorities = authorities; + this.enabled = enabled; + this.lastPasswordResetDate = lastPasswordResetDate; + } + + @JsonIgnore + public Long getId() { + return id; + } + + @Override + public String getUsername() { + return username; + } + + @JsonIgnore + @Override + public boolean isAccountNonExpired() { + return true; + } + + @JsonIgnore + @Override + public boolean isAccountNonLocked() { + return true; + } + + @JsonIgnore + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + public String getFirstname() { + return firstname; + } + + public String getLastname() { + return lastname; + } + + public String getEmail() { + return email; + } + + @JsonIgnore + @Override + public String getPassword() { + return password; + } + + @Override + public Collection getAuthorities() { + return authorities; + } + + @Override + public boolean isEnabled() { + return enabled; + } + + @JsonIgnore + public Date getLastPasswordResetDate() { + return lastPasswordResetDate; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/AbstractimageFilePath.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/AbstractimageFilePath.java new file mode 100755 index 0000000000..9cc13cd4df --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/AbstractimageFilePath.java @@ -0,0 +1,178 @@ +package com.salesmanager.shop.utils; + +import java.util.Properties; + +import javax.annotation.Resource; + +import org.apache.commons.lang3.StringUtils; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.shop.constants.Constants; + + + + + +public abstract class AbstractimageFilePath implements ImageFilePath { + + + public abstract String getBasePath(MerchantStore store); + + public abstract void setBasePath(String basePath); + + public abstract void setContentUrlPath(String contentUrl); + + protected static final String CONTEXT_PATH = "CONTEXT_PATH"; + + public @Resource(name="shopizer-properties") Properties properties = new Properties();//shopizer-properties + + + public Properties getProperties() { + return properties; + } + + public void setProperties(Properties properties) { + this.properties = properties; + } + + /** + * Builds a static content image file path that can be used by image servlet + * utility for getting the physical image + * @param store + * @param imageName + * @return + */ + public String buildStaticImageUtils(MerchantStore store, String imageName) { + StringBuilder imgName = new StringBuilder().append(getBasePath(store)).append(Constants.FILES_URI).append(Constants.SLASH).append(store.getCode()).append(Constants.SLASH).append(FileContentType.IMAGE.name()).append(Constants.SLASH); + if(!StringUtils.isBlank(imageName)) { + imgName.append(imageName); + } + return imgName.toString(); + + } + + /** + * Builds a static content image file path that can be used by image servlet + * utility for getting the physical image by specifying the image type + * @param store + * @param imageName + * @return + */ + public String buildStaticImageUtils(MerchantStore store, String type, String imageName) { + StringBuilder imgName = new StringBuilder().append(getBasePath(store)).append(Constants.FILES_URI).append(Constants.SLASH).append(store.getCode()).append(Constants.SLASH).append(type).append(Constants.SLASH); + if(!StringUtils.isBlank(imageName)) { + imgName.append(imageName); + } + return imgName.toString(); + + } + + /** + * Builds a manufacturer image file path that can be used by image servlet + * utility for getting the physical image + * @param store + * @param manufacturer + * @param imageName + * @return + */ + public String buildManufacturerImageUtils(MerchantStore store, Manufacturer manufacturer, String imageName) { + return new StringBuilder().append(getBasePath(store)).append(Constants.SLASH).append(store.getCode()).append(Constants.SLASH). + append(FileContentType.MANUFACTURER.name()).append(Constants.SLASH) + .append(manufacturer.getId()).append(Constants.SLASH) + .append(imageName).toString(); + } + + /** + * Builds a product image file path that can be used by image servlet + * utility for getting the physical image + * @param store + * @param product + * @param imageName + * @return + */ + public String buildProductImageUtils(MerchantStore store, Product product, String imageName) { + return new StringBuilder().append(getBasePath(store)).append(Constants.PRODUCTS_URI).append(Constants.SLASH).append(store.getCode()).append(Constants.SLASH) + .append(product.getSku()).append(Constants.SLASH).append(Constants.SMALL_IMAGE).append(Constants.SLASH).append(imageName).toString(); + } + + /** + * Builds a default product image file path that can be used by image servlet + * utility for getting the physical image + * @param store + * @param sku + * @param imageName + * @return + */ + public String buildProductImageUtils(MerchantStore store, String sku, String imageName) { + return new StringBuilder().append(getBasePath(store)).append(Constants.PRODUCTS_URI).append(Constants.SLASH).append(store.getCode()).append(Constants.SLASH) + .append(sku).append(Constants.SLASH).append(Constants.SMALL_IMAGE).append(Constants.SLASH).append(imageName).toString(); + } + + /** + * Builds a large product image file path that can be used by the image servlet + * @param store + * @param sku + * @param imageName + * @return + */ + public String buildLargeProductImageUtils(MerchantStore store, String sku, String imageName) { + return new StringBuilder().append(getBasePath(store)).append(Constants.SLASH).append(store.getCode()).append(Constants.SLASH) + .append(sku).append(Constants.SLASH).append(Constants.SMALL_IMAGE).append(Constants.SLASH).append(imageName).toString(); + } + + + + /** + * Builds a merchant store logo path + * @param store + * @return + */ + public String buildStoreLogoFilePath(MerchantStore store) { + return new StringBuilder().append(getBasePath(store)).append(Constants.FILES_URI).append(Constants.SLASH).append(store.getCode()).append(Constants.SLASH).append(FileContentType.LOGO).append(Constants.SLASH) + .append(store.getStoreLogo()).toString(); + } + + /** + * Builds product property image url path + * @param store + * @param imageName + * @return + */ + public String buildProductPropertyImageFilePath(MerchantStore store, String imageName) { + return new StringBuilder().append(getBasePath(store)).append(Constants.SLASH).append(store.getCode()).append(Constants.SLASH).append(FileContentType.PROPERTY).append(Constants.SLASH) + .append(imageName).toString(); + } + + public String buildProductPropertyImageUtils(MerchantStore store, String imageName) { + return new StringBuilder().append(getBasePath(store)).append(Constants.FILES_URI).append(Constants.SLASH).append(store.getCode()).append("/").append(FileContentType.PROPERTY).append("/") + .append(imageName).toString(); + } + + public String buildCustomTypeImageUtils(MerchantStore store, String imageName, FileContentType type) { + return new StringBuilder().append(getBasePath(store)).append(Constants.FILES_URI).append(Constants.SLASH).append(store.getCode()).append("/").append(type).append("/") + .append(imageName).toString(); + } + + /** + * Builds static file url path + * @param store + * @param imageName + * @return + */ + public String buildStaticContentFilePath(MerchantStore store, String fileName) { + StringBuilder sb = new StringBuilder().append(getBasePath(store)).append(Constants.FILES_URI).append(Constants.SLASH).append(store.getCode()).append(Constants.SLASH); + if(!StringUtils.isBlank(fileName)) { + sb.append(fileName); + } + return sb.toString(); + } + + + + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/AdminAccessDeniedHandler.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/AdminAccessDeniedHandler.java new file mode 100755 index 0000000000..96cfc59b5b --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/AdminAccessDeniedHandler.java @@ -0,0 +1,33 @@ +package com.salesmanager.shop.utils; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; + +public class AdminAccessDeniedHandler implements AccessDeniedHandler { + + @Override + public void handle(HttpServletRequest request, + HttpServletResponse response, + AccessDeniedException accessDeniedException) throws IOException, + ServletException { + response.sendRedirect(request.getContextPath() + getAccessDeniedUrl()); + + } + + public String getAccessDeniedUrl() { + return accessDeniedUrl; + } + + public void setAccessDeniedUrl(String accessDeniedUrl) { + this.accessDeniedUrl = accessDeniedUrl; + } + + private String accessDeniedUrl = null; + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/AppConfiguration.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/AppConfiguration.java new file mode 100755 index 0000000000..acc2a3b524 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/AppConfiguration.java @@ -0,0 +1,37 @@ +package com.salesmanager.shop.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.Properties; + +@Component +public class AppConfiguration { + + private static final Logger LOGGER = LoggerFactory.getLogger(AppConfiguration.class); + public Properties properties; + + public Properties getProperties() { + return properties; + } + + public void setProperties(Properties properties) { + this.properties = properties; + } + + public AppConfiguration() {} + + public String getProperty(String propertyKey) { + + if(properties!=null) { + return properties.getProperty(propertyKey); + } else { + LOGGER.warn("Application properties are not loaded"); + return null; + } + + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/AuthorizationUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/AuthorizationUtils.java new file mode 100644 index 0000000000..18d03c68e2 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/AuthorizationUtils.java @@ -0,0 +1,46 @@ +package com.salesmanager.shop.utils; + +import java.util.Arrays; +import java.util.List; + +import javax.inject.Inject; + +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.store.api.exception.UnauthorizedException; +import com.salesmanager.shop.store.controller.user.facade.UserFacade; + +/** + * Performs authorization check for REST Api + * - check if user is in role + * - check if user can perform actions on marchant + * @author carlsamson + * + */ +@Component +public class AuthorizationUtils { + + @Inject + private UserFacade userFacade; + + public String authenticatedUser() { + String authenticatedUser = userFacade.authenticatedUser(); + if (authenticatedUser == null) { + throw new UnauthorizedException(); + } + return authenticatedUser; + } + + public void authorizeUser(String authenticatedUser, List roles, MerchantStore store) { + userFacade.authorizedGroup(authenticatedUser, roles); + if (!userFacade.userInRoles(authenticatedUser, Arrays.asList(Constants.GROUP_SUPERADMIN))) { + if (!userFacade.authorizedStore(authenticatedUser, store.getCode())) { + throw new UnauthorizedException("Operation unauthorized for user [" + authenticatedUser + + "] and store [" + store.getCode() + "]"); + } + } + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/BeanUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/BeanUtils.java new file mode 100755 index 0000000000..e91be20bd8 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/BeanUtils.java @@ -0,0 +1,65 @@ +package com.salesmanager.shop.utils; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class BeanUtils +{ + private BeanUtils(){ + + } + + public static BeanUtils newInstance(){ + return new BeanUtils(); + } + + @SuppressWarnings( "nls" ) + public Object getPropertyValue( Object bean, String property ) + throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException + { + + if (bean == null) { + throw new IllegalArgumentException("No bean specified"); + } + if(property == null){ + + throw new IllegalArgumentException("No name specified for bean class '" + bean.getClass() + "'"); + } + Class beanClass = bean.getClass(); + PropertyDescriptor propertyDescriptor = getPropertyDescriptor( beanClass, property ); + if ( propertyDescriptor == null ) + { + throw new IllegalArgumentException( "No such property " + property + " for " + beanClass + " exists" ); + } + + Method readMethod = propertyDescriptor.getReadMethod(); + if ( readMethod == null ) + { + throw new IllegalStateException( "No getter available for property " + property + " on " + beanClass ); + } + return readMethod.invoke( bean ); + } + + private PropertyDescriptor getPropertyDescriptor( Class beanClass, String propertyname ) + throws IntrospectionException + { + BeanInfo beanInfo = Introspector.getBeanInfo( beanClass ); + PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); + PropertyDescriptor propertyDescriptor = null; + for ( int i = 0; i < propertyDescriptors.length; i++ ) + { + PropertyDescriptor currentPropertyDescriptor = propertyDescriptors[i]; + if ( currentPropertyDescriptor.getName().equals( propertyname ) ) + { + propertyDescriptor = currentPropertyDescriptor; + } + + } + return propertyDescriptor; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/CaptchaRequestUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/CaptchaRequestUtils.java new file mode 100755 index 0000000000..fe47fd75ab --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/CaptchaRequestUtils.java @@ -0,0 +1,112 @@ +package com.salesmanager.shop.utils; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.salesmanager.core.business.utils.CoreConfiguration; +import com.salesmanager.shop.constants.ApplicationConstants; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.inject.Inject; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Creates a request to reCaptcha 2 + * https://www.google.com/recaptcha/api/siteverify + * Throws an exception if it can't connect to reCaptcha + * returns true or false if validation has passed + * @author carlsamson + * + */ +@Component +public class CaptchaRequestUtils { + + @Inject + private CoreConfiguration configuration; //for reading public and secret key + + private static final String SUCCESS_INDICATOR = "success"; + + @Value("${config.recaptcha.secretKey}") + private String secretKey; + + public boolean checkCaptcha(String gRecaptchaResponse) throws Exception { + + HttpClient client = HttpClientBuilder.create().build(); + + String url = configuration.getProperty(ApplicationConstants.RECAPTCHA_URL);; + + List data = new ArrayList(); + data.add(new BasicNameValuePair("secret", secretKey)); + data.add(new BasicNameValuePair("response", gRecaptchaResponse)); + + + // Create a method instance. + HttpPost post = new HttpPost(url); + post.setEntity(new UrlEncodedFormEntity(data,StandardCharsets.UTF_8)); + + boolean checkCaptcha = false; + + + try { + // Execute the method. + HttpResponse httpResponse = client.execute(post); + int statusCode = httpResponse.getStatusLine().getStatusCode(); + + if (statusCode != HttpStatus.SC_OK) { + throw new Exception("Got an invalid response from reCaptcha " + url + " [" + httpResponse.getStatusLine() + "]"); + } + + // Read the response body. + HttpEntity entity = httpResponse.getEntity(); + byte[] responseBody =EntityUtils.toByteArray(entity); + + + // Deal with the response. + // Use caution: ensure correct character encoding and is not binary data + //System.out.println(new String(responseBody)); + + String json = new String(responseBody); + + Map map = new HashMap(); + ObjectMapper mapper = new ObjectMapper(); + + map = mapper.readValue(json, + new TypeReference>(){}); + + String successInd = map.get(SUCCESS_INDICATOR); + + if(StringUtils.isBlank(successInd)) { + throw new Exception("Unreadable response from reCaptcha " + json); + } + + Boolean responseBoolean = Boolean.valueOf(successInd); + + if(responseBoolean) { + checkCaptcha = true; + } + + return checkCaptcha; + + } finally { + // Release the connection. + post.releaseConnection(); + } + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/CloudFilePathUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/CloudFilePathUtils.java new file mode 100755 index 0000000000..a6b3384324 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/CloudFilePathUtils.java @@ -0,0 +1,74 @@ +package com.salesmanager.shop.utils; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.shop.constants.Constants; + +@Component +public class CloudFilePathUtils extends AbstractimageFilePath { + + private String basePath = Constants.STATIC_URI; + private String contentUrl = null; + + @Override + public String getBasePath(MerchantStore store) { + //store has no incidence, basepath drives the url + return basePath; + } + + @Override + public void setBasePath(String basePath) { + this.basePath = basePath; + } + @Override + public String getContextPath() { + return super.getProperties().getProperty(CONTEXT_PATH); + } + + /** + * Builds a static content image file path that can be used by image servlet + * utility for getting the physical image + * @param store + * @param imageName + * @return + */ + @Override + public String buildStaticImageUtils(MerchantStore store, String imageName) { + StringBuilder imgName = new StringBuilder().append(getBasePath(store)).append(Constants.FILES_URI).append(Constants.SLASH).append(store.getCode()).append(Constants.SLASH); + if(!StringUtils.isBlank(imageName)) { + imgName.append(imageName); + } + return imgName.toString(); + + } + + /** + * Builds a static content image file path that can be used by image servlet + * utility for getting the physical image by specifying the image type + * @param store + * @param imageName + * @return + */ + @Override + public String buildStaticImageUtils(MerchantStore store, String type, String imageName) { + StringBuilder imgName = new StringBuilder().append(getBasePath(store)).append(Constants.FILES_URI).append(Constants.SLASH).append(store.getCode()).append(Constants.SLASH); + if(type!=null && !FileContentType.IMAGE.name().equals(type)) { + imgName.append(type).append(Constants.SLASH); + } + if(!StringUtils.isBlank(imageName)) { + imgName.append(imageName); + } + return imgName.toString(); + + } + + @Override + public void setContentUrlPath(String contentUrl) { + this.contentUrl = contentUrl; + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/DateUtil.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/DateUtil.java new file mode 100755 index 0000000000..bfc2a3ae18 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/DateUtil.java @@ -0,0 +1,178 @@ +/* + * Licensed to csti consulting + * You may obtain a copy of the License at + * + * http://www.csticonsulting.com + * Copyright (c) 2006-Aug 24, 2010 Consultation CS-TI inc. + * + * 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 com.salesmanager.shop.utils; + +import com.salesmanager.core.business.constants.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + + + +public class DateUtil { + + private Date startDate = new Date(new Date().getTime()); + private Date endDate = new Date(new Date().getTime()); + private static final Logger LOGGER = LoggerFactory.getLogger(DateUtil.class); + private final static String LONGDATE_FORMAT = "EEE, d MMM yyyy HH:mm:ss Z"; + + + + /** + * Generates a time stamp + * yyyymmddhhmmss + * @return + */ + public static String generateTimeStamp() { + SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmSS"); + return format.format(new Date()); + } + + /** + * yyyy-MM-dd + * + * @param dt + * @return + */ + public static String formatDate(Date dt) { + + if (dt == null) + dt = new Date(); + SimpleDateFormat format = new SimpleDateFormat(Constants.DEFAULT_DATE_FORMAT); + return format.format(dt); + + } + + public static String formatYear(Date dt) { + + if (dt == null) + return null; + SimpleDateFormat format = new SimpleDateFormat(Constants.DEFAULT_DATE_FORMAT_YEAR); + return format.format(dt); + + } + + public static String formatLongDate(Date date) { + + if (date == null) + return null; + SimpleDateFormat format = new SimpleDateFormat(LONGDATE_FORMAT); + return format.format(date); + + } + + /** + * yy-MMM-dd + * + * @param dt + * @return + */ + public static String formatDateMonthString(Date dt) { + + if (dt == null) + return null; + SimpleDateFormat format = new SimpleDateFormat(Constants.DEFAULT_DATE_FORMAT); + return format.format(dt); + + } + + public static Date getDate(String date) throws Exception { + DateFormat myDateFormat = new SimpleDateFormat(Constants.DEFAULT_DATE_FORMAT); + return myDateFormat.parse(date); + } + + public static Date addDaysToCurrentDate(int days) { + Calendar c = Calendar.getInstance(); + c.setTime(new Date()); + c.add(Calendar.DATE, days); + return c.getTime(); + + } + + public static Date getDate() { + + return new Date(new Date().getTime()); + + } + + public static String getPresentDate() { + + Date dt = new Date(); + + SimpleDateFormat format = new SimpleDateFormat(Constants.DEFAULT_DATE_FORMAT); + return format.format(new Date(dt.getTime())); + } + + public static String getPresentYear() { + + Date dt = new Date(); + + SimpleDateFormat format = new SimpleDateFormat("yyyy"); + return format.format(new Date(dt.getTime())); + } + + public static boolean dateBeforeEqualsDate(Date firstDate, Date compareDate) { + + + if(firstDate==null || compareDate==null) { + return true; + } + + if (firstDate.compareTo(compareDate) > 0) { + return false; + } else if (firstDate.compareTo(compareDate) < 0) { + return true; + } else if (firstDate.compareTo(compareDate) == 0) { + return true; + } else { + return false; + } + + } + + public void processPostedDates(HttpServletRequest request) { + Date dt = new Date(); + DateFormat myDateFormat = new SimpleDateFormat(Constants.DEFAULT_DATE_FORMAT); + Date sDate = null; + Date eDate = null; + try { + if (request.getParameter("startdate") != null) { + sDate = myDateFormat.parse(request.getParameter("startdate")); + } + if (request.getParameter("enddate") != null) { + eDate = myDateFormat.parse(request.getParameter("enddate")); + } + this.startDate = sDate; + this.endDate = eDate; + } catch (Exception e) { + LOGGER.error("",e); + this.startDate = new Date(dt.getTime()); + this.endDate = new Date(dt.getTime()); + } + } + + public Date getEndDate() { + return endDate; + } + + public Date getStartDate() { + return startDate; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/EmailTemplatesUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/EmailTemplatesUtils.java new file mode 100755 index 0000000000..e49362e7ad --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/EmailTemplatesUtils.java @@ -0,0 +1,498 @@ +package com.salesmanager.shop.utils; + +import com.salesmanager.core.business.modules.email.Email; +import com.salesmanager.core.business.services.catalog.pricing.PricingService; +import com.salesmanager.core.business.services.catalog.product.ProductService; +import com.salesmanager.core.business.services.reference.country.CountryService; +import com.salesmanager.core.business.services.reference.zone.ZoneService; +import com.salesmanager.core.business.services.system.EmailService; +import com.salesmanager.core.model.customer.Customer; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.order.Order; +import com.salesmanager.core.model.order.OrderTotal; +import com.salesmanager.core.model.order.orderproduct.OrderProduct; +import com.salesmanager.core.model.order.orderstatus.OrderStatusHistory; +import com.salesmanager.core.model.reference.country.Country; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.core.model.reference.zone.Zone; +import com.salesmanager.shop.constants.ApplicationConstants; +import com.salesmanager.shop.constants.EmailConstants; +import com.salesmanager.shop.model.customer.PersistableCustomer; +import com.salesmanager.shop.model.shop.ContactForm; +import org.apache.commons.lang3.StringUtils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import javax.inject.Inject; +import java.util.Date; +import java.util.Locale; +import java.util.Map; + + +@Component +public class EmailTemplatesUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(EmailTemplatesUtils.class); + + @Inject + private EmailService emailService; + + @Inject + private LabelUtils messages; + + @Inject + private CountryService countryService; + + @Inject + private ProductService productService; + + @Inject + private ZoneService zoneService; + + @Inject + private PricingService pricingService; + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + @Inject + private EmailUtils emailUtils; + + @Inject + private FilePathUtils filePathUtils; + + private final static String LINE_BREAK = "
    "; + private final static String TABLE = ""; + private final static String CLOSING_TABLE = "
    "; + private final static String TR = ""; + private final static String TR_BORDER = ""; + private final static String CLOSING_TR = ""; + private final static String TD = ""; + private final static String CLOSING_TD = ""; + + + /** + * Sends an email to the customer after a completed order + * @param customer + * @param order + * @param customerLocale + * @param language + * @param merchantStore + * @param contextPath + */ + @Async + public void sendOrderEmail(String toEmail, Customer customer, Order order, Locale customerLocale, Language language, MerchantStore merchantStore, String contextPath) { + /** issue with putting that elsewhere **/ + LOGGER.info( "Sending welcome email to customer" ); + try { + + Map zones = zoneService.getZones(language); + + Map countries = countryService.getCountriesMap(language); + + //format Billing address + StringBuilder billing = new StringBuilder(); + if(StringUtils.isBlank(order.getBilling().getCompany())) { + billing.append(order.getBilling().getFirstName()).append(" ") + .append(order.getBilling().getLastName()).append(LINE_BREAK); + } else { + billing.append(order.getBilling().getCompany()).append(LINE_BREAK); + } + billing.append(order.getBilling().getAddress()).append(LINE_BREAK); + billing.append(order.getBilling().getCity()).append(", "); + + if(order.getBilling().getZone()!=null) { + Zone zone = zones.get(order.getBilling().getZone().getCode()); + if(zone!=null) { + billing.append(zone.getName()); + } + billing.append(LINE_BREAK); + } else if(!StringUtils.isBlank(order.getBilling().getState())) { + billing.append(order.getBilling().getState()).append(LINE_BREAK); + } + Country country = countries.get(order.getBilling().getCountry().getIsoCode()); + if(country!=null) { + billing.append(country.getName()).append(" "); + } + billing.append(order.getBilling().getPostalCode()); + + + //format shipping address + StringBuilder shipping = null; + if(order.getDelivery()!=null && !StringUtils.isBlank(order.getDelivery().getFirstName())) { + shipping = new StringBuilder(); + if(StringUtils.isBlank(order.getDelivery().getCompany())) { + shipping.append(order.getDelivery().getFirstName()).append(" ") + .append(order.getDelivery().getLastName()).append(LINE_BREAK); + } else { + shipping.append(order.getDelivery().getCompany()).append(LINE_BREAK); + } + shipping.append(order.getDelivery().getAddress()).append(LINE_BREAK); + shipping.append(order.getDelivery().getCity()).append(", "); + + if(order.getDelivery().getZone()!=null) { + Zone zone = zones.get(order.getDelivery().getZone().getCode()); + if(zone!=null) { + shipping.append(zone.getName()); + } + shipping.append(LINE_BREAK); + } else if(!StringUtils.isBlank(order.getDelivery().getState())) { + shipping.append(order.getDelivery().getState()).append(LINE_BREAK); + } + Country deliveryCountry = countries.get(order.getDelivery().getCountry().getIsoCode()); + if(country!=null) { + shipping.append(deliveryCountry.getName()).append(" "); + } + shipping.append(order.getDelivery().getPostalCode()); + } + + if(shipping==null && StringUtils.isNotBlank(order.getShippingModuleCode())) { + //TODO IF HAS NO SHIPPING + shipping = billing; + } + + //format order + //String storeUri = FilePathUtils.buildStoreUri(merchantStore, contextPath); + StringBuilder orderTable = new StringBuilder(); + orderTable.append(TABLE); + for(OrderProduct product : order.getOrderProducts()) { + //Product productModel = productService.getByCode(product.getSku(), language); + orderTable.append(TR); + orderTable.append(TD).append(product.getProductName()).append(" - ").append(product.getSku()).append(CLOSING_TD); + orderTable.append(TD).append(messages.getMessage("label.quantity", customerLocale)).append(": ").append(product.getProductQuantity()).append(CLOSING_TD); + orderTable.append(TD).append(pricingService.getDisplayAmount(product.getOneTimeCharge(), merchantStore)).append(CLOSING_TD); + orderTable.append(CLOSING_TR); + } + + //order totals + for(OrderTotal total : order.getOrderTotal()) { + orderTable.append(TR_BORDER); + //orderTable.append(TD); + //orderTable.append(CLOSING_TD); + orderTable.append(TD); + orderTable.append(CLOSING_TD); + orderTable.append(TD); + orderTable.append(""); + if(total.getModule().equals("tax")) { + orderTable.append(total.getText()).append(": "); + + } else { + //if(total.getModule().equals("total") || total.getModule().equals("subtotal")) { + //} + orderTable.append(messages.getMessage(total.getOrderTotalCode(), customerLocale)).append(": "); + //if(total.getModule().equals("total") || total.getModule().equals("subtotal")) { + + //} + } + orderTable.append(""); + orderTable.append(CLOSING_TD); + orderTable.append(TD); + orderTable.append(""); + + orderTable.append(pricingService.getDisplayAmount(total.getValue(), merchantStore)); + + orderTable.append(""); + orderTable.append(CLOSING_TD); + orderTable.append(CLOSING_TR); + } + orderTable.append(CLOSING_TABLE); + + Map templateTokens = emailUtils.createEmailObjectsMap(contextPath, merchantStore, messages, customerLocale); + templateTokens.put(EmailConstants.LABEL_HI, messages.getMessage("label.generic.hi", customerLocale)); + templateTokens.put(EmailConstants.EMAIL_CUSTOMER_FIRSTNAME, order.getBilling().getFirstName()); + templateTokens.put(EmailConstants.EMAIL_CUSTOMER_LASTNAME, order.getBilling().getLastName()); + + String[] params = {String.valueOf(order.getId())}; + String[] dt = {DateUtil.formatDate(order.getDatePurchased())}; + templateTokens.put(EmailConstants.EMAIL_ORDER_NUMBER, messages.getMessage("email.order.confirmation", params, customerLocale)); + templateTokens.put(EmailConstants.EMAIL_ORDER_DATE, messages.getMessage("email.order.ordered", dt, customerLocale)); + templateTokens.put(EmailConstants.EMAIL_ORDER_THANKS, messages.getMessage("email.order.thanks",customerLocale)); + templateTokens.put(EmailConstants.ADDRESS_BILLING, billing.toString()); + + templateTokens.put(EmailConstants.ORDER_PRODUCTS_DETAILS, orderTable.toString()); + templateTokens.put(EmailConstants.EMAIL_ORDER_DETAILS_TITLE, messages.getMessage("label.order.details",customerLocale)); + templateTokens.put(EmailConstants.ADDRESS_BILLING_TITLE, messages.getMessage("label.customer.billinginformation",customerLocale)); + templateTokens.put(EmailConstants.PAYMENT_METHOD_TITLE, messages.getMessage("label.order.paymentmode",customerLocale)); + templateTokens.put(EmailConstants.PAYMENT_METHOD_DETAILS, messages.getMessage(new StringBuilder().append("payment.type.").append(order.getPaymentType().name()).toString(),customerLocale,order.getPaymentType().name())); + + if(StringUtils.isNotBlank(order.getShippingModuleCode())) { + //templateTokens.put(EmailConstants.SHIPPING_METHOD_DETAILS, messages.getMessage(new StringBuilder().append("module.shipping.").append(order.getShippingModuleCode()).toString(),customerLocale,order.getShippingModuleCode())); + templateTokens.put(EmailConstants.SHIPPING_METHOD_DETAILS, messages.getMessage(new StringBuilder().append("module.shipping.").append(order.getShippingModuleCode()).toString(),new String[]{merchantStore.getStorename()},customerLocale)); + templateTokens.put(EmailConstants.ADDRESS_SHIPPING_TITLE, messages.getMessage("label.order.shippingmethod",customerLocale)); + templateTokens.put(EmailConstants.ADDRESS_DELIVERY_TITLE, messages.getMessage("label.customer.shippinginformation",customerLocale)); + templateTokens.put(EmailConstants.SHIPPING_METHOD_TITLE, messages.getMessage("label.customer.shippinginformation",customerLocale)); + templateTokens.put(EmailConstants.ADDRESS_DELIVERY, shipping.toString()); + } else { + templateTokens.put(EmailConstants.SHIPPING_METHOD_DETAILS, ""); + templateTokens.put(EmailConstants.ADDRESS_SHIPPING_TITLE, ""); + templateTokens.put(EmailConstants.ADDRESS_DELIVERY_TITLE, ""); + templateTokens.put(EmailConstants.SHIPPING_METHOD_TITLE, ""); + templateTokens.put(EmailConstants.ADDRESS_DELIVERY, ""); + } + + String status = messages.getMessage("label.order." + order.getStatus().name(), customerLocale, order.getStatus().name()); + String[] statusMessage = {DateUtil.formatDate(order.getDatePurchased()),status}; + templateTokens.put(EmailConstants.ORDER_STATUS, messages.getMessage("email.order.status", statusMessage, customerLocale)); + + + String[] title = {merchantStore.getStorename(), String.valueOf(order.getId())}; + Email email = new Email(); + email.setFrom(merchantStore.getStorename()); + email.setFromEmail(merchantStore.getStoreEmailAddress()); + email.setSubject(messages.getMessage("email.order.title", title, customerLocale)); + email.setTo(toEmail); + email.setTemplateName(EmailConstants.EMAIL_ORDER_TPL); + email.setTemplateTokens(templateTokens); + + LOGGER.debug( "Sending email to {} for order id {} ",customer.getEmailAddress(), order.getId() ); + emailService.sendHtmlEmail(merchantStore, email); + + } catch (Exception e) { + LOGGER.error("Error occured while sending order confirmation email ",e); + } + + } + + /** + * Sends an email to the customer after registration + * @param request + * @param customer + * @param merchantStore + * @param customerLocale + */ + @Async + public void sendRegistrationEmail( + PersistableCustomer customer, MerchantStore merchantStore, + Locale customerLocale, String contextPath) { + /** issue with putting that elsewhere **/ + LOGGER.info( "Sending welcome email to customer" ); + try { + + Map templateTokens = emailUtils.createEmailObjectsMap(contextPath, merchantStore, messages, customerLocale); + templateTokens.put(EmailConstants.LABEL_HI, messages.getMessage("label.generic.hi", customerLocale)); + templateTokens.put(EmailConstants.EMAIL_CUSTOMER_FIRSTNAME, customer.getBilling().getFirstName()); + templateTokens.put(EmailConstants.EMAIL_CUSTOMER_LASTNAME, customer.getBilling().getLastName()); + String[] greetingMessage = {merchantStore.getStorename(),filePathUtils.buildCustomerUri(merchantStore,contextPath),merchantStore.getStoreEmailAddress()}; + templateTokens.put(EmailConstants.EMAIL_CUSTOMER_GREETING, messages.getMessage("email.customer.greeting", greetingMessage, customerLocale)); + templateTokens.put(EmailConstants.EMAIL_USERNAME_LABEL, messages.getMessage("label.generic.username",customerLocale)); + templateTokens.put(EmailConstants.EMAIL_PASSWORD_LABEL, messages.getMessage("label.generic.password",customerLocale)); + templateTokens.put(EmailConstants.CUSTOMER_ACCESS_LABEL, messages.getMessage("label.customer.accessportal",customerLocale)); + templateTokens.put(EmailConstants.ACCESS_NOW_LABEL, messages.getMessage("label.customer.accessnow",customerLocale)); + templateTokens.put(EmailConstants.EMAIL_USER_NAME, customer.getUserName()); + templateTokens.put(EmailConstants.EMAIL_CUSTOMER_PASSWORD, customer.getPassword()); + + //shop url + String customerUrl = filePathUtils.buildStoreUri(merchantStore, contextPath); + templateTokens.put(EmailConstants.CUSTOMER_ACCESS_URL, customerUrl); + + Email email = new Email(); + email.setFrom(merchantStore.getStorename()); + email.setFromEmail(merchantStore.getStoreEmailAddress()); + email.setSubject(messages.getMessage("email.newuser.title",customerLocale)); + email.setTo(customer.getEmailAddress()); + email.setTemplateName(EmailConstants.EMAIL_CUSTOMER_TPL); + email.setTemplateTokens(templateTokens); + + LOGGER.debug( "Sending email to {} on their registered email id {} ",customer.getBilling().getFirstName(),customer.getEmailAddress() ); + emailService.sendHtmlEmail(merchantStore, email); + + } catch (Exception e) { + LOGGER.error("Error occured while sending welcome email ",e); + } + + } + + @Async + public void sendContactEmail( + ContactForm contact, MerchantStore merchantStore, + Locale storeLocale, String contextPath) { + /** issue with putting that elsewhere **/ + LOGGER.info( "Sending email to store owner" ); + try { + + Map templateTokens = emailUtils.createEmailObjectsMap(contextPath, merchantStore, messages, storeLocale); + + templateTokens.put(EmailConstants.EMAIL_CONTACT_NAME, contact.getName()); + templateTokens.put(EmailConstants.EMAIL_CONTACT_EMAIL, contact.getEmail()); + templateTokens.put(EmailConstants.EMAIL_CONTACT_CONTENT, contact.getComment()); + + String[] contactSubject = {contact.getSubject()}; + + templateTokens.put(EmailConstants.EMAIL_CUSTOMER_CONTACT, messages.getMessage("email.contact",contactSubject, storeLocale)); + templateTokens.put(EmailConstants.EMAIL_CONTACT_NAME_LABEL, messages.getMessage("label.entity.name",storeLocale)); + templateTokens.put(EmailConstants.EMAIL_CONTACT_EMAIL_LABEL, messages.getMessage("label.generic.email",storeLocale)); + + + + Email email = new Email(); + email.setFrom(contact.getName()); + //since shopizer sends email to store email, sender is store email + email.setFromEmail(merchantStore.getStoreEmailAddress()); + email.setSubject(messages.getMessage("email.contact.title",storeLocale)); + //contact has to be delivered to store owner, receiver is store email + email.setTo(merchantStore.getStoreEmailAddress()); + email.setTemplateName(EmailConstants.EMAIL_CONTACT_TMPL); + email.setTemplateTokens(templateTokens); + + LOGGER.debug( "Sending contact email"); + emailService.sendHtmlEmail(merchantStore, email); + + } catch (Exception e) { + LOGGER.error("Error occured while sending contact email ",e); + } + + } + + /** + * Send an email to the customer with last order status + * @param request + * @param customer + * @param order + * @param merchantStore + * @param customerLocale + */ + @Async + public void sendUpdateOrderStatusEmail( + Customer customer, Order order, OrderStatusHistory lastHistory, MerchantStore merchantStore, + Locale customerLocale, String contextPath) { + /** issue with putting that elsewhere **/ + LOGGER.info( "Sending order status email to customer" ); + try { + + + Map templateTokens = emailUtils.createEmailObjectsMap(contextPath, merchantStore, messages, customerLocale); + + templateTokens.put(EmailConstants.LABEL_HI, messages.getMessage("label.generic.hi", customerLocale)); + templateTokens.put(EmailConstants.EMAIL_CUSTOMER_FIRSTNAME, customer.getBilling().getFirstName()); + templateTokens.put(EmailConstants.EMAIL_CUSTOMER_LASTNAME, customer.getBilling().getLastName()); + + String[] statusMessageText = {String.valueOf(order.getId()),DateUtil.formatDate(order.getDatePurchased())}; + String status = messages.getMessage("label.order." + order.getStatus().name(), customerLocale, order.getStatus().name()); + String[] statusMessage = {DateUtil.formatDate(lastHistory.getDateAdded()),status}; + + String comments = lastHistory.getComments(); + if(StringUtils.isBlank(comments)) { + comments = messages.getMessage("label.order." + order.getStatus().name(), customerLocale, order.getStatus().name()); + } + + templateTokens.put(EmailConstants.EMAIL_ORDER_STATUS_TEXT, messages.getMessage("email.order.statustext", statusMessageText, customerLocale)); + templateTokens.put(EmailConstants.EMAIL_ORDER_STATUS, messages.getMessage("email.order.status", statusMessage, customerLocale)); + templateTokens.put(EmailConstants.EMAIL_TEXT_STATUS_COMMENTS, comments); + + + Email email = new Email(); + email.setFrom(merchantStore.getStorename()); + email.setFromEmail(merchantStore.getStoreEmailAddress()); + email.setSubject(messages.getMessage("email.order.status.title",new String[]{String.valueOf(order.getId())},customerLocale)); + email.setTo(customer.getEmailAddress()); + email.setTemplateName(EmailConstants.ORDER_STATUS_TMPL); + email.setTemplateTokens(templateTokens); + + + + emailService.sendHtmlEmail(merchantStore, email); + + } catch (Exception e) { + LOGGER.error("Error occured while sending order download email ",e); + } + + } + + /** + * Send download email instructions to customer + * @param customer + * @param order + * @param merchantStore + * @param customerLocale + * @param contextPath + */ + @Async + public void sendOrderDownloadEmail( + Customer customer, Order order, MerchantStore merchantStore, + Locale customerLocale, String contextPath) { + /** issue with putting that elsewhere **/ + LOGGER.info( "Sending download email to customer" ); + try { + + Map templateTokens = emailUtils.createEmailObjectsMap(contextPath, merchantStore, messages, customerLocale); + templateTokens.put(EmailConstants.LABEL_HI, messages.getMessage("label.generic.hi", customerLocale)); + templateTokens.put(EmailConstants.EMAIL_CUSTOMER_FIRSTNAME, customer.getBilling().getFirstName()); + templateTokens.put(EmailConstants.EMAIL_CUSTOMER_LASTNAME, customer.getBilling().getLastName()); + String[] downloadMessage = {String.valueOf(ApplicationConstants.MAX_DOWNLOAD_DAYS), String.valueOf(order.getId()), filePathUtils.buildCustomerUri(merchantStore, contextPath), merchantStore.getStoreEmailAddress()}; + templateTokens.put(EmailConstants.EMAIL_ORDER_DOWNLOAD, messages.getMessage("email.order.download.text", downloadMessage, customerLocale)); + templateTokens.put(EmailConstants.CUSTOMER_ACCESS_LABEL, messages.getMessage("label.customer.accessportal",customerLocale)); + templateTokens.put(EmailConstants.ACCESS_NOW_LABEL, messages.getMessage("label.customer.accessnow",customerLocale)); + + //shop url + String customerUrl = filePathUtils.buildStoreUri(merchantStore, contextPath); + templateTokens.put(EmailConstants.CUSTOMER_ACCESS_URL, customerUrl); + + String[] orderInfo = {String.valueOf(order.getId())}; + + Email email = new Email(); + email.setFrom(merchantStore.getStorename()); + email.setFromEmail(merchantStore.getStoreEmailAddress()); + email.setSubject(messages.getMessage("email.order.download.title", orderInfo, customerLocale)); + email.setTo(customer.getEmailAddress()); + email.setTemplateName(EmailConstants.EMAIL_ORDER_DOWNLOAD_TPL); + email.setTemplateTokens(templateTokens); + + LOGGER.debug( "Sending email to {} with download info",customer.getEmailAddress() ); + emailService.sendHtmlEmail(merchantStore, email); + + } catch (Exception e) { + LOGGER.error("Error occured while sending order download email ",e); + } + + } + + /** + * Sends a change password notification email to the Customer + * @param customer + * @param merchantStore + * @param customerLocale + * @param contextPath + */ + @Async + public void changePasswordNotificationEmail( + Customer customer, MerchantStore merchantStore, + Locale customerLocale, String contextPath) { + LOGGER.debug( "Sending change password email" ); + try { + + + Map templateTokens = emailUtils.createEmailObjectsMap(contextPath, merchantStore, messages, customerLocale); + + templateTokens.put(EmailConstants.LABEL_HI, messages.getMessage("label.generic.hi", customerLocale)); + templateTokens.put(EmailConstants.EMAIL_CUSTOMER_FIRSTNAME, customer.getBilling().getFirstName()); + templateTokens.put(EmailConstants.EMAIL_CUSTOMER_LASTNAME, customer.getBilling().getLastName()); + + String[] date = {DateUtil.formatLongDate(new Date())}; + + templateTokens.put(EmailConstants.EMAIL_NOTIFICATION_MESSAGE, messages.getMessage("label.notification.message.passwordchanged", date, customerLocale)); + + + Email email = new Email(); + email.setFrom(merchantStore.getStorename()); + email.setFromEmail(merchantStore.getStoreEmailAddress()); + email.setSubject(messages.getMessage("label.notification.title.passwordchanged",customerLocale)); + email.setTo(customer.getEmailAddress()); + email.setTemplateName(EmailConstants.EMAIL_NOTIFICATION_TMPL); + email.setTemplateTokens(templateTokens); + + + + emailService.sendHtmlEmail(merchantStore, email); + + } catch (Exception e) { + LOGGER.error("Error occured while sending change password email ",e); + } + + } + +} \ No newline at end of file diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/EmailUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/EmailUtils.java new file mode 100755 index 0000000000..617dfb2add --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/EmailUtils.java @@ -0,0 +1,64 @@ +package com.salesmanager.shop.utils; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import javax.inject.Inject; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.shop.constants.Constants; + + +@Component +public class EmailUtils { + + private final static String EMAIL_STORE_NAME = "EMAIL_STORE_NAME"; + private final static String EMAIL_FOOTER_COPYRIGHT = "EMAIL_FOOTER_COPYRIGHT"; + private final static String EMAIL_DISCLAIMER = "EMAIL_DISCLAIMER"; + private final static String EMAIL_SPAM_DISCLAIMER = "EMAIL_SPAM_DISCLAIMER"; + private final static String EMAIL_ADMIN_LABEL = "EMAIL_ADMIN_LABEL"; + private final static String LOGOPATH = "LOGOPATH"; + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + /** + * Builds generic html email information + * @param store + * @param messages + * @param locale + * @return + */ + public Map createEmailObjectsMap(String contextPath, MerchantStore store, LabelUtils messages, Locale locale){ + + Map templateTokens = new HashMap(); + + String[] adminNameArg = {store.getStorename()}; + String[] adminEmailArg = {store.getStoreEmailAddress()}; + String[] copyArg = {store.getStorename(), DateUtil.getPresentYear()}; + + templateTokens.put(EMAIL_ADMIN_LABEL, messages.getMessage("email.message.from", adminNameArg, locale)); + templateTokens.put(EMAIL_STORE_NAME, store.getStorename()); + templateTokens.put(EMAIL_FOOTER_COPYRIGHT, messages.getMessage("email.copyright", copyArg, locale)); + templateTokens.put(EMAIL_DISCLAIMER, messages.getMessage("email.disclaimer", adminEmailArg, locale)); + templateTokens.put(EMAIL_SPAM_DISCLAIMER, messages.getMessage("email.spam.disclaimer", locale)); + + if(store.getStoreLogo()!=null) { + //TODO revise + StringBuilder logoPath = new StringBuilder(); + String scheme = Constants.HTTP_SCHEME; + logoPath.append(""); + templateTokens.put(LOGOPATH, logoPath.toString()); + } else { + templateTokens.put(LOGOPATH, store.getStorename()); + } + + return templateTokens; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/Enum.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/Enum.java new file mode 100755 index 0000000000..fb7ee0f6ef --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/Enum.java @@ -0,0 +1,27 @@ +package com.salesmanager.shop.utils; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.validation.Constraint; +import javax.validation.Payload; + +@Documented +@Constraint(validatedBy = {EnumValidator.class}) +@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER }) +@Retention(RetentionPolicy.RUNTIME) +public @interface Enum +{ + public abstract String message() default "Invalid value. This is not permitted."; + + public abstract Class[] groups() default {}; + + public abstract Class[] payload() default {}; + + public abstract Class> enumClass(); + + public abstract boolean ignoreCase() default false; +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/EnumValidator.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/EnumValidator.java new file mode 100755 index 0000000000..b6edf6b52f --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/EnumValidator.java @@ -0,0 +1,45 @@ +package com.salesmanager.shop.utils; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + + +/** + * Validates values of a String used as payload in REST service + * Solution taken from https://funofprograming.wordpress.com/2016/09/29/java-enum-validator/ + * @author c.samson + * + */ +public class EnumValidator implements ConstraintValidator +{ + private Enum annotation; + + @Override + public void initialize(Enum annotation) + { + this.annotation = annotation; + } + + @Override + public boolean isValid(String valueForValidation, ConstraintValidatorContext constraintValidatorContext) + { + boolean result = false; + + Object[] enumValues = this.annotation.enumClass().getEnumConstants(); + + if(enumValues != null) + { + for(Object enumValue:enumValues) + { + if(valueForValidation.equals(enumValue.toString()) + || (this.annotation.ignoreCase() && valueForValidation.equalsIgnoreCase(enumValue.toString()))) + { + result = true; + break; + } + } + } + + return result; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/FieldMatch.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/FieldMatch.java new file mode 100755 index 0000000000..328ba6cdb3 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/FieldMatch.java @@ -0,0 +1,70 @@ +/** + * + */ +package com.salesmanager.shop.utils; + +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.validation.Constraint; +import javax.validation.Payload; + + +/** + * + * Validation annotation to validate that 2 fields have the same value. + * An array of fields and their matching confirmation fields can be supplied. + * + * Example, compare 1 pair of fields: + * @FieldMatch(first = "password", second = "confirmPassword", message = "The password fields must match") + * + * Example, compare more than 1 pair of fields: + * @FieldMatch.List({ + * @FieldMatch(first = "password", second = "confirmPassword", message = "The password fields must match"), + * @FieldMatch(first = "email", second = "confirmEmail", message = "The email fields must match")}) + * + * @author Umesh Awasthi + * + */ + +@Constraint(validatedBy = FieldMatchValidator.class) +@Documented +@Target({TYPE, ANNOTATION_TYPE}) +@Retention(RUNTIME) +public @interface FieldMatch +{ + + String message() default "Fields are not matching"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + /** + * @return The first field + */ + String first(); + + /** + * @return The second field + */ + String second(); + + /** + * Defines several @FieldMatch annotations on the same element + * + * @see FieldMatch + */ + @Target({TYPE, ANNOTATION_TYPE}) + @Retention(RUNTIME) + @Documented + @interface List + { + FieldMatch[] value(); + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/FieldMatchValidator.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/FieldMatchValidator.java new file mode 100755 index 0000000000..6cebb4cd11 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/FieldMatchValidator.java @@ -0,0 +1,45 @@ +package com.salesmanager.shop.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + + +public class FieldMatchValidator implements ConstraintValidator +{ + + private static final Logger LOG=LoggerFactory.getLogger(FieldMatchValidator.class); + private String firstFieldName; + private String secondFieldName; + private BeanUtils beanUtils; + + @Override + public void initialize(final FieldMatch constraintAnnotation) + { + this.firstFieldName = constraintAnnotation.first(); + this.secondFieldName = constraintAnnotation.second(); + this.beanUtils=BeanUtils.newInstance(); + } + + @SuppressWarnings( "nls" ) + @Override + public boolean isValid(final Object value, final ConstraintValidatorContext context) + { + try + { + final Object firstObj = this.beanUtils.getPropertyValue(value, this.firstFieldName); + final Object secondObj = this.beanUtils.getPropertyValue(value, this.secondFieldName); + return firstObj == null && secondObj == null || firstObj != null && firstObj.equals(secondObj); + } + catch (final Exception ex) + { + LOG.info( "Error while getting values from object", ex ); + return false; + + } + + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/FileNameUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/FileNameUtils.java new file mode 100644 index 0000000000..ade3b4d2f0 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/FileNameUtils.java @@ -0,0 +1,37 @@ +package com.salesmanager.shop.utils; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +/** + * Determines if a file name seems to be valid. + * This utility opens the door to the validation of a file name and see if it meets the following + * + * - has an extension + * - has a name + * - ... your own rules ... + * @author carlsamson + * + */ +@Component +public class FileNameUtils { + + public boolean validFileName(String fileName) { + + boolean validName = true; + + //has an extention + if(StringUtils.isEmpty(FilenameUtils.getExtension(fileName))) { + validName = false; + } + + //has a filename + if(StringUtils.isEmpty(FilenameUtils.getBaseName(fileName))) { + validName = false; + } + + return validName; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/FilePathUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/FilePathUtils.java new file mode 100755 index 0000000000..4223013b0c --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/FilePathUtils.java @@ -0,0 +1,226 @@ +package com.salesmanager.shop.utils; + +import static com.salesmanager.shop.constants.Constants.ADMIN_URI; +import static com.salesmanager.shop.constants.Constants.BLANK; +import static com.salesmanager.shop.constants.Constants.CATEGORY_URI; +import static com.salesmanager.shop.constants.Constants.DEFAULT_DOMAIN_NAME; +import static com.salesmanager.shop.constants.Constants.FILES_URI; +import static com.salesmanager.shop.constants.Constants.HTTP_SCHEME; +import static com.salesmanager.shop.constants.Constants.ORDER_DOWNLOAD_URI; +import static com.salesmanager.shop.constants.Constants.SHOP_URI; +import static com.salesmanager.shop.constants.Constants.SLASH; +import static com.salesmanager.shop.constants.Constants.STATIC_URI; +import static com.salesmanager.shop.constants.Constants.URL_EXTENSION; + +import java.net.URL; +import java.util.Properties; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.business.utils.CoreConfiguration; +import com.salesmanager.core.model.catalog.product.file.DigitalProduct; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.model.order.ReadableOrderProductDownload; + +@Component +public class FilePathUtils { + + private static final String DOWNLOADS = "/downloads/"; + private static final String DOUBLE_SLASH = "://"; + private static final String CONTEXT_PATH = "CONTEXT_PATH"; + public static final String X_FORWARDED_HOST = "X-Forwarded-Host"; + public static final String HTTP = "http://"; + public static final String HTTPS = "https://"; + + @Inject + private CoreConfiguration coreConfiguration; + + @Inject + @Qualifier("img") + private ImageFilePath imageUtils; + + @Resource(name = "shopizer-properties") + public Properties properties = new Properties(); + + /** + * Builds a static content content file path that can be used by image + * servlet utility for getting the physical image Example: + * /files// + */ + public String buildStaticFilePath(String storeCode, String fileName) { + String path = FILES_URI + SLASH + storeCode + SLASH; + if (StringUtils.isNotBlank(fileName)) { + return path + fileName; + } + return path; + } + + public String buildStaticFilePath(MerchantStore store) { + return STATIC_URI + FILES_URI + SLASH + store.getCode() + SLASH; + } + + /** + * Example: /admin/files/downloads// + */ + public String buildAdminDownloadProductFilePath(MerchantStore store, DigitalProduct digitalProduct) { + return ADMIN_URI + FILES_URI + DOWNLOADS + store.getCode() + SLASH + digitalProduct.getProductFileName(); + } + + /** + * Example: /shop/order/download/.html + */ + public String buildOrderDownloadProductFilePath(MerchantStore store, ReadableOrderProductDownload digitalProduct, + Long orderId) { + return SHOP_URI + ORDER_DOWNLOAD_URI + SLASH + orderId + SLASH + digitalProduct.getId() + URL_EXTENSION; + } + + /** + * Example: //files//STATIC_FILE/ Or + * example: /:////files// + */ + public String buildStaticFileAbsolutePath(MerchantStore store, String fileName) { + if (StringUtils.isNotBlank(imageUtils.getBasePath(store)) + && imageUtils.getBasePath(store).startsWith(HTTP_SCHEME)) { + return imageUtils.getBasePath(store) + FILES_URI + SLASH + store.getCode() + SLASH + + FileContentType.STATIC_FILE + SLASH + fileName; + } else { + String scheme = this.getScheme(store); + return scheme + SLASH + coreConfiguration.getProperty("CONTEXT_PATH") + + buildStaticFilePath(store.getCode(), fileName); + } + } + + /** + * Example: http[s]://// + */ + public String buildStoreUri(MerchantStore store, HttpServletRequest request) { + return buildBaseUrl(request, store); + } + + /** + * \/ + */ + public String buildStoreUri(MerchantStore store, String contextPath) { + return normalizePath(contextPath); + } + + public String buildRelativeStoreUri(HttpServletRequest request, MerchantStore store) { + return "" + normalizePath(request.getContextPath()); + } + + /** + * Access to the customer section + */ + public String buildCustomerUri(MerchantStore store, String contextPath) { + return buildStoreUri(store, contextPath); + } + + public String buildAdminUri(MerchantStore store, HttpServletRequest request) { + String baseUrl = buildBaseUrl(request, store); + return baseUrl + ADMIN_URI; + } + + public String buildCategoryUrl(MerchantStore store, String contextPath, String url) { + return buildStoreUri(store, contextPath) + SHOP_URI + CATEGORY_URI + SLASH + url + URL_EXTENSION; + } + + public String buildProductUrl(MerchantStore store, String contextPath, String url) { + return buildStoreUri(store, contextPath) + SHOP_URI + Constants.PRODUCT_URI + SLASH + url + URL_EXTENSION; + } + + public String getContextPath() { + return properties.getProperty(CONTEXT_PATH); + } + + private String normalizePath(String path) { + if (SLASH.equals(path)) { + return BLANK; + } else { + return path; + } + } + + private String getDomainName(String domainName) { + if (StringUtils.isBlank(domainName)) { + return DEFAULT_DOMAIN_NAME; + } else { + return domainName; + } + } + + private String getScheme(MerchantStore store) { + String baseScheme = store.getDomainName(); + if (baseScheme != null && baseScheme.length() > 0 + && baseScheme.charAt(baseScheme.length() - 1) == Constants.SLASH.charAt(0)) { + baseScheme = baseScheme.substring(0, baseScheme.length() - 1); + } + // end no more + return validUrl(baseScheme); + } + + public String validUrl(final String url) { + if (!StringUtils.isBlank(url) && !url.startsWith(HTTP) && !url.startsWith(HTTP)) { + return HTTPS + url; + } + return url; + } + + private String buildBaseUrl(HttpServletRequest request, MerchantStore store) { + String contextPath = normalizePath(request.getContextPath()); + String scheme = getScheme(store); + return scheme + DOUBLE_SLASH + contextPath; + } + + public String buildBaseUrl(String contextPath, MerchantStore store) { + String normalizePath = normalizePath(contextPath); + String scheme = getScheme(store); + return scheme + SLASH + normalizePath; + } + + /** + * Requires web server headers to build image URL for social media + * sharing.
    + * + * Nginx configuration example: + * + *

    +	 *     proxy_set_header X-Forwarded-Proto $scheme;
    +	 *     proxy_set_header X-Forwarded-Host $scheme://$host;
    +	 *     proxy_set_header X-Forwarded-Server $host;
    +	 * 
    + * + * @param merchantStore + * @param request + * @return + */ + public String buildStoreForwardedUri(MerchantStore merchantStore, HttpServletRequest request) { + String uri; + if (StringUtils.isNotEmpty(request.getHeader(X_FORWARDED_HOST))) { + uri = request.getHeader(X_FORWARDED_HOST); + } else { + uri = buildStoreUri(merchantStore, request); + } + return uri; + } + + public boolean isValidURL(String urlString) + { + try + { + URL url = new URL(urlString); + url.toURI(); + return true; + } catch (Exception exception) + { + return false; + } + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/GeoLocationUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/GeoLocationUtils.java new file mode 100755 index 0000000000..5a7d033322 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/GeoLocationUtils.java @@ -0,0 +1,31 @@ +package com.salesmanager.shop.utils; + +import javax.servlet.http.HttpServletRequest; + +public class GeoLocationUtils { + + + private static final String[] HEADERS_TO_TRY = { + "X-Forwarded-For", + "Proxy-Client-IP", + "WL-Proxy-Client-IP", + "HTTP_X_FORWARDED_FOR", + "HTTP_X_FORWARDED", + "HTTP_X_CLUSTER_CLIENT_IP", + "HTTP_CLIENT_IP", + "HTTP_FORWARDED_FOR", + "HTTP_FORWARDED", + "HTTP_VIA", + "REMOTE_ADDR" }; + + public static String getClientIpAddress(HttpServletRequest request) { + for (String header : HEADERS_TO_TRY) { + String ip = request.getHeader(header); + if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) { + return ip; + } + } + return request.getRemoteAddr(); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/ImageFilePath.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/ImageFilePath.java new file mode 100755 index 0000000000..7f2cb2e9d0 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/ImageFilePath.java @@ -0,0 +1,112 @@ +package com.salesmanager.shop.utils; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.merchant.MerchantStore; + +public interface ImageFilePath { + + /** + * Context path configured in shopizer-properties.xml + * @return + */ + public String getContextPath(); + + + public String getBasePath(MerchantStore store); + + /** + * Builds a static content image file path that can be used by image servlet + * utility for getting the physical image + * @param store + * @param imageName + * @return + */ + public String buildStaticImageUtils(MerchantStore store, String imageName); + + /** + * Builds a static content image file path that can be used by image servlet + * utility for getting the physical image by specifying the image type + * @param store + * @param imageName + * @return + */ + public String buildStaticImageUtils(MerchantStore store, String type, String imageName); + + /** + * Builds a manufacturer image file path that can be used by image servlet + * utility for getting the physical image + * @param store + * @param manufacturer + * @param imageName + * @return + */ + public String buildManufacturerImageUtils(MerchantStore store, Manufacturer manufacturer, String imageName); + + /** + * Builds a product image file path that can be used by image servlet + * utility for getting the physical image + * @param store + * @param product + * @param imageName + * @return + */ + public String buildProductImageUtils(MerchantStore store, Product product, String imageName); + + /** + * Builds a default product image file path that can be used by image servlet + * utility for getting the physical image + * @param store + * @param sku + * @param imageName + * @return + */ + public String buildProductImageUtils(MerchantStore store, String sku, String imageName); + + /** + * Builds a large product image file path that can be used by the image servlet + * @param store + * @param sku + * @param imageName + * @return + */ + public String buildLargeProductImageUtils(MerchantStore store, String sku, String imageName); + + + + /** + * Builds a merchant store logo path + * @param store + * @return + */ + public String buildStoreLogoFilePath(MerchantStore store); + + /** + * Builds product property image url path + * @param store + * @param imageName + * @return + */ + public String buildProductPropertyImageUtils(MerchantStore store, String imageName); + + /** + * A custom file type image handler + * @param store + * @param imageName + * @param type + * @return + */ + String buildCustomTypeImageUtils(MerchantStore store, String imageName, FileContentType type); + + + /** + * Builds static file path + * @param store + * @param fileName + * @return + */ + public String buildStaticContentFilePath(MerchantStore store, String fileName); + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/ImageFilePathUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/ImageFilePathUtils.java new file mode 100755 index 0000000000..81394efddc --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/ImageFilePathUtils.java @@ -0,0 +1,45 @@ +package com.salesmanager.shop.utils; + +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.shop.constants.Constants; + +/** + * To be used when using an external web server for managing images + * + + + * @author c.samson + * + */ +@Component +public class ImageFilePathUtils extends AbstractimageFilePath{ + + private String basePath = Constants.STATIC_URI; + private String contentUrl = null; + + @Override + public String getBasePath(MerchantStore store) { + return basePath; + } + + @Override + public void setBasePath(String basePath) { + this.basePath = basePath; + } + @Override + public String getContextPath() { + return super.getProperties().getProperty(CONTEXT_PATH); + } + + @Override + public void setContentUrlPath(String contentUrl) { + this.contentUrl = contentUrl; + + } + + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/LabelUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/LabelUtils.java new file mode 100755 index 0000000000..11f2bb3b7d --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/LabelUtils.java @@ -0,0 +1,36 @@ +package com.salesmanager.shop.utils; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +import java.util.Locale; + +public class LabelUtils implements ApplicationContextAware { + + + private ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + this.applicationContext = applicationContext; + + } + + public String getMessage(String key, Locale locale) { + return applicationContext.getMessage(key, null, locale); + } + + public String getMessage(String key, Locale locale, String defaultValue) { + try { + return applicationContext.getMessage(key, null, locale); + } catch(Exception ignore) {} + return defaultValue; + } + + public String getMessage(String key, String[] args, Locale locale) { + return applicationContext.getMessage(key, args, locale); + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/LanguageUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/LanguageUtils.java new file mode 100755 index 0000000000..638f3832fe --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/LanguageUtils.java @@ -0,0 +1,186 @@ +package com.salesmanager.shop.utils; + +import static com.salesmanager.core.business.constants.Constants.DEFAULT_STORE; + +import java.util.Locale; +import java.util.Optional; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.support.RequestContextUtils; +import com.salesmanager.core.business.exception.ServiceException; +import com.salesmanager.core.business.services.reference.language.LanguageService; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; +import com.salesmanager.shop.store.controller.store.facade.StoreFacade; + +@Component +public class LanguageUtils { + + protected final Log logger = LogFactory.getLog(getClass()); + public static final String REQUEST_PARAMATER_STORE = "store"; + + private static final String ALL_LANGUALES = "_all"; + + @Inject + LanguageService languageService; + + @Autowired + private StoreFacade storeFacade; + + public Language getServiceLanguage(String lang) { + Language l = null; + if (!StringUtils.isBlank(lang)) { + try { + l = languageService.getByCode(lang); + } catch (ServiceException e) { + logger.error("Cannot retrieve language " + lang, e); + } + } + + if (l == null) { + l = languageService.defaultLanguage(); + } + + return l; + } + + /** + * Determines request language based on store rules + * + * @param request + * @return + */ + public Language getRequestLanguage(HttpServletRequest request, HttpServletResponse response) { + + Locale locale = null; + + Language language = (Language) request.getSession().getAttribute(Constants.LANGUAGE); + MerchantStore store = + (MerchantStore) request.getSession().getAttribute(Constants.MERCHANT_STORE); + + + + if (language == null) { + try { + + locale = LocaleContextHolder.getLocale();// should be browser locale + + + + if (store != null) { + language = store.getDefaultLanguage(); + if (language != null) { + locale = languageService.toLocale(language, store); + if (locale != null) { + LocaleContextHolder.setLocale(locale); + } + request.getSession().setAttribute(Constants.LANGUAGE, language); + } + + if (language == null) { + language = languageService.toLanguage(locale); + request.getSession().setAttribute(Constants.LANGUAGE, language); + } + + } + + } catch (Exception e) { + if (language == null) { + try { + language = languageService.getByCode(Constants.DEFAULT_LANGUAGE); + } catch (Exception ignore) { + } + } + } + } else { + + + Locale localeFromContext = LocaleContextHolder.getLocale();// should be browser locale + if (!language.getCode().equals(localeFromContext.getLanguage())) { + // get locale context + language = languageService.toLanguage(localeFromContext); + } + + } + + if (language != null) { + locale = languageService.toLocale(language, store); + } else { + language = languageService.toLanguage(locale); + } + + LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request); + if (localeResolver != null) { + localeResolver.setLocale(request, response, locale); + } + response.setLocale(locale); + request.getSession().setAttribute(Constants.LANGUAGE, language); + + return language; + } + + /** + * Should be used by rest web services + * + * @param request + * @param store + * @return + * @throws Exception + */ + public Language getRESTLanguage(HttpServletRequest request, NativeWebRequest webRequest) { + + Validate.notNull(request, "HttpServletRequest must not be null"); + + try { + Language language = null; + + String lang = request.getParameter(Constants.LANG); + + if (StringUtils.isBlank(lang)) { + if (language == null) { + String storeValue = Optional.ofNullable(webRequest.getParameter(REQUEST_PARAMATER_STORE)) + .filter(StringUtils::isNotBlank).orElse(DEFAULT_STORE); + if(!StringUtils.isBlank(storeValue)) { + try { + MerchantStore storeModel = storeFacade.get(storeValue); + language = storeModel.getDefaultLanguage(); + } catch (Exception e) { + logger.warn("Cannot get store with code [" + storeValue + "]"); + } + + } else { + language = languageService.defaultLanguage(); + } + + } + } else { + if(!ALL_LANGUALES.equals(lang)) { + language = languageService.getByCode(lang); + if (language == null) { + language = languageService.defaultLanguage(); + } + } + } + + //if language is null then underlying facade must load all languages + return language; + + } catch (ServiceException e) { + throw new ServiceRuntimeException(e); + } + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/LocalImageFilePathUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/LocalImageFilePathUtils.java new file mode 100755 index 0000000000..85d11c97f4 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/LocalImageFilePathUtils.java @@ -0,0 +1,170 @@ +package com.salesmanager.shop.utils; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.salesmanager.core.model.catalog.product.Product; +import com.salesmanager.core.model.content.FileContentType; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.shop.constants.Constants; +import com.salesmanager.shop.model.catalog.manufacturer.Manufacturer; + + + + +@Component +public class LocalImageFilePathUtils extends AbstractimageFilePath{ + + private String basePath = Constants.STATIC_URI; + + private static final String SCHEME = "http://"; + private String contentUrl = null; + + + @Autowired + private ServerConfig serverConfig; + + @Override + public String getBasePath(MerchantStore store) { + if(StringUtils.isBlank(contentUrl)) { + String host = new StringBuilder().append(SCHEME).append(serverConfig.getApplicationHost()).toString(); + return new StringBuilder().append(this.getScheme(store, host)).append(basePath).toString(); + } else { + return new StringBuilder().append(contentUrl).append(basePath).toString(); + } + } + + @Override + public void setBasePath(String context) { + this.basePath = context; + } + + /** + * Builds a static content image file path that can be used by image servlet + * utility for getting the physical image + * @param store + * @param imageName + * @return + */ + public String buildStaticimageUtils(MerchantStore store, String imageName) { + StringBuilder imgName = new StringBuilder().append(getBasePath(store)).append(Constants.FILES_URI).append(Constants.SLASH).append(store.getCode()).append("/").append(FileContentType.IMAGE.name()).append("/"); + if(!StringUtils.isBlank(imageName)) { + imgName.append(imageName); + } + return imgName.toString(); + + } + + /** + * Builds a static content image file path that can be used by image servlet + * utility for getting the physical image by specifying the image type + * @param store + * @param imageName + * @return + */ + public String buildStaticimageUtils(MerchantStore store, String type, String imageName) { + StringBuilder imgName = new StringBuilder().append(getBasePath(store)).append(Constants.FILES_URI).append(Constants.SLASH).append(store.getCode()).append("/").append(type).append("/"); + if(!StringUtils.isBlank(imageName)) { + imgName.append(imageName); + } + return imgName.toString(); + + } + + /** + * Builds a manufacturer image file path that can be used by image servlet + * utility for getting the physical image + * @param store + * @param manufacturer + * @param imageName + * @return + */ + public String buildManufacturerimageUtils(MerchantStore store, Manufacturer manufacturer, String imageName) { + return new StringBuilder().append(getBasePath(store)).append("/").append(store.getCode()).append("/"). + append(FileContentType.MANUFACTURER.name()).append("/") + .append(manufacturer.getId()).append("/") + .append(imageName).toString(); + } + + /** + * Builds a product image file path that can be used by image servlet + * utility for getting the physical image + * @param store + * @param product + * @param imageName + * @return + */ + public String buildProductimageUtils(MerchantStore store, Product product, String imageName) { + return new StringBuilder().append(getBasePath(store)).append("/products/").append(store.getCode()).append("/") + .append(product.getSku()).append("/").append("LARGE").append("/").append(imageName).toString(); + } + + /** + * Builds a default product image file path that can be used by image servlet + * utility for getting the physical image + * @param store + * @param sku + * @param imageName + * @return + */ + public String buildProductimageUtils(MerchantStore store, String sku, String imageName) { + return new StringBuilder().append(getBasePath(store)).append("/products/").append(store.getCode()).append("/") + .append(sku).append("/").append("LARGE").append("/").append(imageName).toString(); + } + + /** + * Builds a large product image file path that can be used by the image servlet + * @param store + * @param sku + * @param imageName + * @return + */ + public String buildLargeProductimageUtils(MerchantStore store, String sku, String imageName) { + return new StringBuilder().append(getBasePath(store)).append("/products/").append(store.getCode()).append("/") + .append(sku).append("/").append("LARGE").append("/").append(imageName).toString(); + } + + + + /** + * Builds a merchant store logo path + * @param store + * @return + */ + public String buildStoreLogoFilePath(MerchantStore store) { + return new StringBuilder().append(getBasePath(store)).append(Constants.FILES_URI).append(Constants.SLASH).append(store.getCode()).append("/").append(FileContentType.LOGO).append("/") + .append(store.getStoreLogo()).toString(); + } + + /** + * Builds product property image url path + * @param store + * @param imageName + * @return + */ + public String buildProductPropertyimageUtils(MerchantStore store, String imageName) { + return new StringBuilder().append(getBasePath(store)).append(Constants.FILES_URI).append(Constants.SLASH).append(store.getCode()).append("/").append(FileContentType.PROPERTY).append("/") + .append(imageName).toString(); + } + + + @Override + public String getContextPath() { + return super.getProperties().getProperty(CONTEXT_PATH); + } + + private String getScheme(MerchantStore store, String derivedHost) { + return store.getDomainName() != null ? store.getDomainName():derivedHost; + } + + @Override + public void setContentUrlPath(String contentUrl) { + this.contentUrl = contentUrl; + } + + + + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/LocaleUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/LocaleUtils.java new file mode 100755 index 0000000000..fdc780efef --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/LocaleUtils.java @@ -0,0 +1,50 @@ +package com.salesmanager.shop.utils; + +import java.util.Locale; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.core.model.reference.language.Language; + + +public class LocaleUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(LocaleUtils.class); + + public static Locale getLocale(Language language) { + + return new Locale(language.getCode()); + + } + + /** + * Creates a Locale object for currency format only with country code + * This method ignoes the language + * @param store + * @return + */ + public static Locale getLocale(MerchantStore store) { + + Locale defaultLocale = Constants.DEFAULT_LOCALE; + Locale[] locales = Locale.getAvailableLocales(); + for(int i = 0; i< locales.length; i++) { + Locale l = locales[i]; + try { + if(l.toLanguageTag().equals(store.getDefaultLanguage().getCode())) { + defaultLocale = l; + break; + } + } catch(Exception e) { + LOGGER.error("An error occured while getting ISO code for locale " + l.toString()); + } + } + + return defaultLocale; + + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/MerchantUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/MerchantUtils.java new file mode 100755 index 0000000000..05dd509d82 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/MerchantUtils.java @@ -0,0 +1,46 @@ +package com.salesmanager.shop.utils; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.text.ParseException; +import java.util.Date; +import java.util.Locale; + +import org.apache.commons.lang3.StringUtils; + +import com.salesmanager.core.model.merchant.MerchantStore; + +public class MerchantUtils { + + public String getFooterMessage(MerchantStore store, String prefix, String suffix) { + + StringBuilder footerMessage = new StringBuilder(); + + if(!StringUtils.isBlank(prefix)) { + footerMessage.append(prefix).append(" "); + } + + Date sinceDate = null; + String inBusinessSince = store.getDateBusinessSince(); + + + return null; + } + + /** + * Locale based bigdecimal parser + * @return + */ + public static BigDecimal getBigDecimal(String bigDecimal) throws ParseException { + NumberFormat decimalFormat = NumberFormat.getInstance(Locale.getDefault()); + BigDecimal value; + if(decimalFormat instanceof DecimalFormat) { + ((DecimalFormat) decimalFormat).setParseBigDecimal(true); + value = (BigDecimal) decimalFormat.parse(bigDecimal); + } else { + value = new BigDecimal(bigDecimal); + } + return value; + } +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/SanitizeUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/SanitizeUtils.java new file mode 100644 index 0000000000..6ac8b9f4dd --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/SanitizeUtils.java @@ -0,0 +1,112 @@ +package com.salesmanager.shop.utils; + +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.lang3.StringEscapeUtils; +import org.apache.commons.lang3.StringUtils; +import org.owasp.validator.html.AntiSamy; +import org.owasp.validator.html.CleanResults; +import org.owasp.validator.html.Policy; + +import com.salesmanager.shop.store.api.exception.ServiceRuntimeException; + +public class SanitizeUtils { + + /** + * should not contain / + */ + private static List blackList = Arrays.asList(';','%', '&', '=', '|', '*', '+', '_', + '^', '%','$','(', ')', '{', '}', '<', '>', '[', + ']', '`', '\'', '~','\\', '?','\''); + + private final static String POLICY_FILE = "antisamy-slashdot.xml"; + + private static Policy policy = null; + + static { + try { + ClassLoader loader = Policy.class.getClassLoader(); + InputStream configStream = loader.getResourceAsStream(POLICY_FILE); + policy = Policy.getInstance(configStream); + + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + } + + private SanitizeUtils() { + //Utility class + } + + public static String getSafeString(String value) { + + try { + + if(policy == null) { + throw new ServiceRuntimeException("Error in " + SanitizeUtils.class.getName() + " html sanitize utils is null"); } + + AntiSamy as = new AntiSamy(); + CleanResults cr = as.scan(value, policy); + + return cr.getCleanHTML(); + + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + + + + } + + + public static String getSafeRequestParamString(String value) { + + StringBuilder safe = new StringBuilder(); + if(StringUtils.isNotEmpty(value)) { + // Fastest way for short strings - https://stackoverflow.com/a/11876086/195904 + for(int i=0; i", "& gt;"); + //value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;"); + //value = value.replaceAll("'", "& #39;"); + value = value.replaceAll("eval\\((.*)\\)", ""); + value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\""); + + value = value.replaceAll("(?i).*?", ""); + value = value.replaceAll("(?i).*?", ""); + value = value.replaceAll("(?i)<.*?javascript:.*?>.*?", ""); + value = value.replaceAll("(?i)<.*?\\s+on.*?>.*?", ""); + //value = value.replaceAll("", ""); + + //return HtmlUtils.htmlEscape(value); + + StringBuilder safe = new StringBuilder(); + if(StringUtils.isNotEmpty(value)) { + // Fastest way for short strings - https://stackoverflow.com/a/11876086/195904 + for(int i=0; i { + + private String applicationHost = null; + + @Override + public void onApplicationEvent(final WebServerInitializedEvent event) { + int port = event.getWebServer().getPort(); + final String host = getHost(); + setApplicationHost(String.join(":", host, String.valueOf(port))); + + } + + private String getHost() { + try { + return InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException e) { + e.printStackTrace(); + return "127.0.0.1"; + } + } + + public String getApplicationHost() { + return applicationHost; + } + + public void setApplicationHost(String applicationHost) { + this.applicationHost = applicationHost; + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/ServiceRequestCriteriaBuilderUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/ServiceRequestCriteriaBuilderUtils.java new file mode 100755 index 0000000000..beda4139a0 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/ServiceRequestCriteriaBuilderUtils.java @@ -0,0 +1,115 @@ +package com.salesmanager.shop.utils; + +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.PropertyAccessor; +import org.springframework.beans.PropertyAccessorFactory; + +import com.salesmanager.core.model.common.Criteria; +import com.salesmanager.core.model.common.CriteriaOrderBy; +import com.salesmanager.core.model.merchant.MerchantStoreCriteria; +import com.salesmanager.shop.store.api.exception.RestApiException; + +public class ServiceRequestCriteriaBuilderUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(ServiceRequestCriteriaBuilderUtils.class); + + /** + * Binds request parameter values to specific request criterias + * @param criteria + * @param mappingFields + * @param request + * @return + * @throws Exception + */ + public static Criteria buildRequestCriterias(Criteria criteria, Map mappingFields, HttpServletRequest request) throws RestApiException { + + if(criteria == null) + throw new RestApiException("A criteria class type must be instantiated"); + + mappingFields.keySet().stream().forEach(p -> { + try { + setValue(criteria, request, p, mappingFields.get(p)); + } catch (Exception e) { + e.printStackTrace(); + } + }); + return criteria; + + + + } + + private static void setValue(Criteria criteria, HttpServletRequest request, String parameterName, String setterValue) throws Exception { + + + try { + + PropertyAccessor criteriaAccessor = PropertyAccessorFactory.forDirectFieldAccess(criteria); + + + String parameterValue = request.getParameter(parameterName); + if(parameterValue == null) return; + // set the property directly, bypassing the mutator (if any) + //String setterName = "set" + WordUtils.capitalize(setterValue); + String setterName = setterValue; + System.out.println("Trying to do this binding " + setterName + "('" + parameterValue + "') on " + criteria.getClass()); + criteriaAccessor.setPropertyValue(setterName, parameterValue); + + } catch(Exception e) { + throw new Exception("An error occured while parameter bindding", e); + } + + + } + + /** deprecated **/ + public static Criteria buildRequest(Map mappingFields, HttpServletRequest request) { + + /** + * Works assuming datatable sends query data + */ + MerchantStoreCriteria criteria = new MerchantStoreCriteria(); + + String searchParam = request.getParameter("search[value]"); + String orderColums = request.getParameter("order[0][column]"); + + if (!StringUtils.isBlank(orderColums)) { + String columnName = request.getParameter("columns[" + orderColums + "][data]"); + String overwriteField = columnName; + if (mappingFields != null && mappingFields.get(columnName) != null) { + overwriteField = mappingFields.get(columnName); + } + criteria.setCriteriaOrderByField(overwriteField); + criteria.setOrderBy( + CriteriaOrderBy.valueOf(request.getParameter("order[0][dir]").toUpperCase())); + } + + String storeName = request.getParameter("storeName"); + criteria.setName(storeName); + + String retailers = request.getParameter("retailers"); + String stores = request.getParameter("stores"); + + try { + boolean retail = Boolean.valueOf(retailers); + boolean sto = Boolean.valueOf(stores); + + criteria.setRetailers(retail); + criteria.setStores(sto); + } catch(Exception e) { + LOGGER.error("Error parsing boolean values",e); + } + + criteria.setSearch(searchParam); + + return criteria; + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/SessionUtil.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/SessionUtil.java new file mode 100755 index 0000000000..4dffe72111 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/SessionUtil.java @@ -0,0 +1,31 @@ +/** + * + */ +package com.salesmanager.shop.utils; + +import javax.servlet.http.HttpServletRequest; + +/** + * @author Umesh Awasthi + * + */ +public class SessionUtil +{ + + + + @SuppressWarnings("unchecked") + public static T getSessionAttribute(final String key, HttpServletRequest request) { + return (T) request.getSession().getAttribute( key ); + } + + public static void removeSessionAttribute(final String key, HttpServletRequest request) { + request.getSession().removeAttribute( key ); + } + + public static void setSessionAttribute(final String key, final Object value, HttpServletRequest request) { + request.getSession().setAttribute( key, value ); + } + + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/TokenizeTool.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/TokenizeTool.java new file mode 100755 index 0000000000..92a22dfd85 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/TokenizeTool.java @@ -0,0 +1,48 @@ +package com.salesmanager.shop.utils; + +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TokenizeTool { + + private final static String CIPHER = "AES/ECB/PKCS5Padding"; + + private static final Logger LOGGER = LoggerFactory.getLogger(TokenizeTool.class); + + private TokenizeTool(){} + + private static SecretKey key = null; + + static { + + try { + + KeyGenerator keygen = KeyGenerator.getInstance("DES"); + key = keygen.generateKey(); + + } catch (Exception e) { + LOGGER.error("Cannot generate key",e); + } + + + + + + } + + public static String tokenizeString(String token) throws Exception { + + Cipher aes = Cipher.getInstance(CIPHER); + aes.init(Cipher.ENCRYPT_MODE, key); + byte[] ciphertext = aes.doFinal(token.getBytes()); + + return new String(ciphertext); + + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/UserUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/UserUtils.java new file mode 100755 index 0000000000..edd8bef56a --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/UserUtils.java @@ -0,0 +1,25 @@ +package com.salesmanager.shop.utils; + +import com.salesmanager.core.model.user.Group; +import com.salesmanager.core.model.user.User; + +import java.util.List; + +public class UserUtils { + + public static boolean userInGroup(User user,String groupName) { + + + + List logedInUserGroups = user.getGroups(); + for(Group group : logedInUserGroups) { + if(group.getGroupName().equals(groupName)) { + return true; + } + } + + return false; + + } + +} diff --git a/sm-shop/src/main/java/com/salesmanager/shop/utils/WebApplicationCacheUtils.java b/sm-shop/src/main/java/com/salesmanager/shop/utils/WebApplicationCacheUtils.java new file mode 100755 index 0000000000..a5505e2338 --- /dev/null +++ b/sm-shop/src/main/java/com/salesmanager/shop/utils/WebApplicationCacheUtils.java @@ -0,0 +1,22 @@ +package com.salesmanager.shop.utils; + +import com.salesmanager.core.business.utils.CacheUtils; +import org.springframework.stereotype.Component; + +import javax.inject.Inject; + +@Component +public class WebApplicationCacheUtils { + + @Inject + private CacheUtils cache; + + public Object getFromCache(String key) throws Exception { + return cache.getFromCache(key); + } + + public void putInCache(String key, Object object) throws Exception { + cache.putInCache(object, key); + } + +} diff --git a/sm-shop/src/main/resources/application.properties b/sm-shop/src/main/resources/application.properties new file mode 100755 index 0000000000..e245149639 --- /dev/null +++ b/sm-shop/src/main/resources/application.properties @@ -0,0 +1,63 @@ +#Spring boot configurations +#logging.config=log4j-shopizer.properties +server.port=8080 + + +#Turn Statistics on +#spring.jpa.properties.hibernate.generate_statistics=true +#default database schema +spring.jpa.properties.hibernate.default_schema=SALESMANAGER +#logging.level.org.hibernate.stat=debug + +# Enable logging to verify that HikariCP is used, the second entry is specific to HikariCP +logging.level.org.hibernate.SQL=ERROR +logging.level.com.zaxxer.hikari.HikariConfig=INFO +#TRACE will print binding +logging.level.org.hibernate.type.descriptor.sql.BasicBinder=INFO + +#when running from IDE (eclipse) or from springboot:run command +#server.contextPath=/shopizer + +logging.level.org.springframework=ERROR +logging.level.com.shopizer=INFO +logging.level.org.hibernate=ERROR +logging.level.org.apache.http=ERROR + +#logging.file=shopizer.log + +#Default Spring white label error page +server.error.whitelabel.enabled=false + +spring.servlet.multipart.max-file-size=4MB +spring.servlet.multipart.max-request-size=10MB + + +#hibernate 5 +spring.jpa.hibernate.use-new-id-generator-mappings=true + + +#Spring boot 2.X +spring.main.allow-bean-definition-overriding: true + +#build informations +application-description=@project.description@ +application-version=@project.version@ +build.timestamp=@maven.build.timestamp@ + +#actuator +management.endpoints.web.exposure.include=* + +management.endpoint.health.show-details=always +management.endpoint.health.show-components=always + +management.health.elasticsearch.enabled=false +management.health.mail.enabled=false +management.health.ping.enabled=true + + + + + + + + diff --git a/sm-shop/src/main/resources/banner.txt b/sm-shop/src/main/resources/banner.txt new file mode 100755 index 0000000000..045a8e68a2 --- /dev/null +++ b/sm-shop/src/main/resources/banner.txt @@ -0,0 +1,9 @@ + _____ _ _ +/ ___|| | (_) +\ `--. | |__ ___ _ __ _ ____ ___ _ __ + `--. \| '_ \ / _ \ | '_ \ | ||_ / / _ \| '__| +/\__/ /| | | || (_) || |_) || | / / | __/| | +\____/ |_| |_| \___/ | .__/ |_|/___| \___||_| + | | + |_| +Shopizer ${application-version} [based on Spring Boot version ${spring-boot.version}] diff --git a/sm-shop/src/main/resources/bundles/messages.properties b/sm-shop/src/main/resources/bundles/messages.properties new file mode 100755 index 0000000000..98ce0dd3e6 --- /dev/null +++ b/sm-shop/src/main/resources/bundles/messages.properties @@ -0,0 +1,220 @@ +message.success=Request completed with success +message.error=An error occurred in this request +message.email.success=Your message has been sent +message.productreview.created=You have successfully created a product review +message.email.error=An error occurred while sending your message, pleas try again later +message.access.denied=Access denied +message.error.shoppingcart.update=An error occurred while updating the shopping cart +message.username.password=Login Failed. Username or Password is incorrect. +message.resource.notfound=The requested page does not exist. +message.fielderror=Field error +message.timeout=The session timed out. +message.error.shipping=An error occurred while estimating shipping costs +NotEmpty=Field required +currentpassword.not.empty=Current password should not be empty +password.notequal=New password and check password should be equals +newpassword.not.empty=New password should not be empty and should be 6 characters long +repeatpassword.not.empty=Check password should not be empty and should be 6 characters long + +NotEmpty.store.storename=The store name should not be empty +NotEmpty.store.storeEmailAddress=Store email address should not be empty +Email.store.storeEmailAddress=Store email address is invalid +NotEmpty.product.productPrice=The product price must be specified +NotEmpty.product.manufacturer=The product manufacturer is required +NotEmpty.price.code=The price code is required +Pattern.price.code=The price code must be alphanumeric +Pattern.product.sku=The sku must be alphanumeric +Pattern.merchant.code=The merchant store code must be alphanumeric +Pattern.optionValue.code=The code must be alphanumeric +NotEmpty.optionValue.code=The code should not be empty +Pattern.option.code=The code must be alphanumeric +NotEmpty.option.code=The code should not be empty +NotEmpty.keyword.keyword=The keyword cannot be empty +NotEmpty.review.description=Your opinion is required +NotEmpty.review.rating=Product rating is required +NotEmpty.group.groupType=Group type is required +NotEmpty.group.groupName=Group name is required + +NotEmpty.customer.userName=User name is required +NotEmpty.customer.firstName=First name is required +NotEmpty.customer.lastName=Last name is required +NotEmpty.customer.address=Street address is required +NotEmpty.customer.address2=Street address is required +NotEmpty.customer.postalCode=Postal code is required +NotEmpty.customer.stateProvince=State / Province is required +NotEmpty.customer.phone=Phone number is required +NotEmpty.customer.city=City is required +NotEmpty.customer.agreement=Please agree to our terms and conditions + +NotEmpty.origin.address=Street address is required +NotEmpty.origin.postalCode=Postal code is required +NotEmpty.origin.city=City is required +NotEmpty.origin.country=Country is required + +NotEmpty.customer.emailAddress=Email address is required +Email.customer.emailAddress=Email address is invalid +NotEmpty.customer.billing.phone=Phone number is required +NotEmpty.customer.billing.address=Street address is required +NotEmpty.customer.billing.city=City is required +NotEmpty.customer.billing.postalCode=Postal code is required +NotEmpty.customer.billing.country=Country is required +NotEmpty.customer.billing.stateProvince=State / Province is required + +NotEmpty.customer.shipping.firstName=Shipping first name should not be empty +NotEmpty.customer.shipping.lastName=Shipping last name should not be empty +NotEmpty.customer.shipping.address=Shipping street address should not be empty +NotEmpty.customer.shipping.city=Shipping city should not be empty +NotEmpty.customer.shipping.postalCode=Shipping postal code should not be empty +NotEmpty.customer.shipping.phone=Shipping phone should not be empty +NotEmpty.customer.shipping.stateProvince=Shipping State / Province is required + +NotEmpty.order.creditcard.number=A valid credit card number is required +NotEmpty.order.creditcard.name=Credit card holder's name is required +NotEmpty.order.creditcard.cvv=Credit card validation digit is required +NotEmpty.contact.name=Contact name is required +NotEmpty.contact.subject=Contact subject is required +NotEmpty.contact.comment=Comment is required +Email.contact.email=Email format is invalid +NotEmpty.contact.captchaResponseField=Captcha answer is required +NotEmpty.contact.captchaChallengeField=Captcha challenge question is required + +message.creditcard.invalid=Credit card details are required +message.order.canprocess=The order can be completed +message.name.required=The object name is required + +message.code.exist=This code already exist +message.name.exist=This name already exist +message.invalid.amount=Invalid amount +message.region.exists=Region already exist +message.region.null=Region cannot be empty +message.invalid.price=Price format is invalid +message.invalid.rate=Rate format is invalid +message.invalid.date=Invalid date format +message.maximumWeight.null=Maximum weight cannot be empty +message.maximumWeight.invalid=Maximum weight needs to be greater than 0 +message.unauthorized=This transaction cannot be completed +message.code.available=This code is available +message.image.height=Image height too large +message.image.width=Image width too large +message.image.size=Image too big +message.number.invalid=Must be a valid number (eg 5) +message.productoption.required=A product attribute/option is required +message.productoptionvalue.required=A product attribute/option value is required +message.product.language=The product has not been configured with this language. Edit the product and configure it with this language. + +message.password.required=A password is required +message.password.repeat.required=Repeated password is required +message.username.required=User name is required +message.username.notfound=User name not found +message.price.cents=Please enter a maximum of 99 cents +message.security.cannotrevoke.superadmin=Can't revoke Super Admin group +message.cannot.empty=can't be empty +message.password.different=New password and repeat password must be identical +message.password.invalid=Invalid password +message.password.length=Password must be at least 6 characters +message.password.reset=Password has been reset +message.password.checkpassword.identical=Both password must match +message.credentials.reset=Credentials have been changed +message.address.enter=Enter your address + +message.security.caanotremovesuperadmin=Can't remove super admin user + +message.group.alerady.exists=The group {0} already exists +message.group.required=The group is required + +message.product.association=This entity is attached to one or more products, remove the association before trying to delete. +message.notexist.customer=Customer does not exist +message.optionset.optionassociationexists=The option association already exist +message.optionset.noassociation=Select an option and an option value + +messages.error.creditcard=Credit card data is invalid +messages.error.creditcard.number=Credit card number is not valid +messages.error.creditcard.dateformat=Credit card expiration date is invalid +messages.error.creditcard.cvc=Credit card verification digits are invalid + + +message.payment.declined=Payment transaction has been declined +message.payment.error=Got an error while processing the payment, please use another payment method + +message.content.missing.agreement=Content with code 'agreement' does not exist + +merchant.storeId.invalid=Please provide a merchant store +merchant.files.invalid=Please provide file(s) to be uploaded. +merchant.zone.invalid=Store state/province is required + +NotEmpty.order.customerFirstName=Customer first name should not be empty +NotEmpty.order.customerLastName=Customer last name should not be empty +NotEmpty.order.customerStreetAddress=Customer street address should not be empty +NotEmpty.order.customerCity=Customer city should not be empty +NotEmpty.order.customerPostCode=Customer postal code should not be empty +NotEmpty.order.customerTelephone=Customer phone should not be empty +Email.order.customerEmailAddress=Customer email address is invalid +NotEmpty.order.customerEmailAddress=Customer email address should not be empty + + +NotEmpty.order.billingName=Billing name should not be empty +NotEmpty.order.billingStreetAddress=Billing street address should not be empty +NotEmpty.order.billingCity=Billing city should not be empty +NotEmpty.order.billingState=Billing state should not be empty +NotEmpty.order.billingPostCode=Billing postal code should not be empty + + +NotEmpty.customer.FirstName=Customer first name should not be empty +NotEmpty.customer.LastName=Customer last name should not be empty +NotEmpty.customer.StreetAddress=Customer street address should not be empty +NotEmpty.customer.City=Customer city should not be empty +NotEmpty.customer.Country=Customer country should not be empty +NotEmpty.customer.PostCode=Customer postal code should not be empty +NotEmpty.customer.Telephone=Customer phone should not be empty +Email.customer.EmailAddress=Customer email address is invalid +NotEmpty.customer.EmailAddress=Customer email address should not be empty + +NotEmpty.customer.billingCompany=Billing company name should not be empty +NotEmpty.customer.billingFirstName=Billing first name should not be empty +NotEmpty.customer.billingLastName=Billing last name should not be empty +NotEmpty.customer.billingStreetAddress=Billing street address should not be empty +NotEmpty.customer.billingCity=Billing city should not be empty +NotEmpty.customer.billingState=Billing state should not be empty +NotEmpty.customer.billingCountry=Billing country should not be empty +NotEmpty.customer.billingPostCode=Billing postal code should not be empty + +NotEmpty.customer.shippingCountry=Shipping country should not be empty + +NotEmpty.taxClass.code=Tax Class code is required +NotEmpty.taxClass.title=Tax Class name is required +message.taxclass.alreadyexist=Tax Class code already exist +NotEmpty.taxRate.code=Tax Rate code must not be empty +NotEmpty.taxRate.unique.code=Tax Rate code must be unique +NotEmpty.taxRate.rateText=Tax Rate must not be empty +NotEmpty.taxRateDescription.name=Tax Rate name must not be empty +NotNull.taxRate.parent=Parent tax rate must be selected + +message.noshipping.configured=No shipping method configured +message.noshipping=No shipping available +message.noshippingerror=No shipping available, please check your shipping country, state / province and postal code + +message.login.duallogin=Dual login not authorized on the same browser + +User.resetPassword.resetSuccess=Successfully changed password, please check your Email +User.resetPassword.wrongSecurityQtn=Wrong Security Question/Answer Entered +User.resetPassword.userNotFound=Specified User Not Found +User.resetPassword.Error=An error occured, please contact the administrator + +validaion.recaptcha.not.matched=Recaptcha does not matched with user input +registration.username.not.empty=Please provide user name +registration.username.length.invalid=User name must be at least 6 characters long +registration.password.not.empty=Please provide a valid password +registration.firstName.invalid=Please provide first name +registration.lastName.invalid=Please provide last name +messages.invalid.email=Please provide a valid email address. +registration.username.already.exists = User with user name already exists for this store. +registration.failed=Unable to complete registration, please try again later +currentpassword.not.empty=Please provide your current password +newpassword.not.empty=Please provide a new password +repeatpassword.not.empty=Please provide repeated password +message.invalidpassword=Invalid password +message.cookie.policy=This website uses cookies to guarantee you the best experience on our website. + +error.code.99=An error occured while trying to process the payment +message.sku.exists= sku already exists for another product + diff --git a/sm-shop/src/main/resources/bundles/messages_fr.properties b/sm-shop/src/main/resources/bundles/messages_fr.properties new file mode 100755 index 0000000000..6023216ec4 --- /dev/null +++ b/sm-shop/src/main/resources/bundles/messages_fr.properties @@ -0,0 +1,218 @@ +message.success=Requête compétée avec succès +message.error=Une erreur est survenue avec cette requête +message.email.success=Votre message a été envoyé avec succès +message.productreview.created=Votre avez créé une revue de produit avec succès +message.email.error=Une erreur est survenue avec l''envoi du message, veuillez essayer plus tard +message.error.shoppingcart.update=Une erreur est survenue pendant la mise à jour du panier d'achat +message.access.denied=Accès refusé +message.username.password=Authentication échouée. Le nom d\\'usager ou le mot de passe est invalide. +message.resource.notfound=La page demandée n'existe pas +message.fielderror=Entrée erronnée +message.timeout=La session est expirée. +message.error.shipping=Une erreur est survenue lors du calcul des coûts d'expédition +NotEmpty=Champs requis +currentpassword.not.empty=Le mot de passe courant ne doit pas être vide +password.notequal=Le nouveau mot de passe et le mot de passe de vérification doivent être identiques +newpassword.not.empty=Le nouveau mot de passe ne doit pas être vide et doit être d''au moins 6 caractères +repeatpassword.not.empty=Le mot de passe de vérification ne doit pas être vide et doit être d''au moins 6 caractères + +NotEmpty.store.storename=Le nom de la boutique ne doit pas être vide +NotEmpty.store.storeEmailAddress=Le email de la boutique ne doit pas être vide +Email.store.storeEmailAddress=Le email est invalide +NotEmpty.product.productPrice=Le prix du produit doit être spécifié +NotEmpty.product.manufacturer=Le manufacturier du produit doit être spécifié +NotEmpty.price.code=Le code de prix doit être spécifié +Pattern.price.code=Le code de prix doit être aplha-numérique +Pattern.product.sku=Le sku doit être aplha-numérique +Pattern.merchant.code=Le code du marchand doit être aplha-numérique +Pattern.optionValue.code=Le code doit être aplha-numérique +NotEmpty.optionValue.code=Le code ne doit pas être vide +Pattern.option.code=Le code doit être aplha-numérique +NotEmpty.option.code=Le code ne doit pas être vide +NotEmpty.keyword.keyword=Le mot clé ne doit pas être vide +NotEmpty.review.description=Votre opinion est requise +NotEmpty.review.rating=Une évaluation du produit est requise +NotEmpty.group.groupType=Le type de groupe est requis +NotEmpty.group.groupName=Le nom du groupe est requis + +NotEmpty.customer.userName=Un nom d''usager est requis +NotEmpty.customer.firstName=Le prénom est requis +NotEmpty.customer.lastName=Le nom est requis +NotEmpty.customer.address=L''addresse est requise +NotEmpty.customer.address2=L'addresse est requise +NotEmpty.customer.postalCode=Le code postal est requis +NotEmpty.customer.stateProvince=L''état / province est requis +NotEmpty.customer.phone=Le téléphone est requis +NotEmpty.customer.city=La ville est requise + +NotEmpty.origin.address=L'addresse est requise +NotEmpty.origin.postalCode=Le code postal est requis +NotEmpty.origin.city=La ville est requise +NotEmpty.origin.country=Le pays est requis + + +NotEmpty.customer.emailAddress=L'adresse couriel est requise +Email.customer.emailAddress=L'adresse couriel est invalide +NotEmpty.customer.billing.phone=Le téléphone est requis +NotEmpty.customer.billing.address=L'addresse est requise +NotEmpty.customer.billing.city=La ville est requise +NotEmpty.customer.billing.postalCode=Le code postal est requis +NotEmpty.customer.billing.country=Le pays est requis +NotEmpty.customer.billing.stateProvince=L'état / province est requis +NotEmpty.customer.agreement=Veuillez accepter nos termes et conditions + +NotEmpty.customer.shipping.firstName=Le prénom à la livraison ne doit pas être vide +NotEmpty.customer.shipping.lastName=Le nom de famille à la livraisonne doit pas être vide +NotEmpty.customer.shipping.address=L'adresse de livraison ne doit pas être vide +NotEmpty.customer.shipping.city=La ville de livraison ne doit pas être vide +NotEmpty.customer.shipping.postalCode=Le code postal de livraison ne doit pas être vide +NotEmpty.customer.shipping.phone=Le numéro de telephone de livraison ne doit pas être vide +NotEmpty.customer.shipping.stateProvince=L'état / province de la livraison est requis + +NotEmpty.order.creditcard.number=Un numéro de carte de crédit valide est requis +NotEmpty.order.creditcard.name=Le nom aparaissant sur la carte de crédit est requis +NotEmpty.order.creditcard.cvv=Les numéros de vérification aparaisasant sur la carte de crédit sont requis +NotEmpty.contact.name=Le nom de la personne contact est requis +NotEmpty.contact.subject=Le sujet du formulaire de contact est requis +NotEmpty.contact.comment=Les commentaires sont requis +Email.contact.email=L'adresse couriel est invalide +NotEmpty.contact.captchaResponseField=La réponse 'Captcha' est requise +NotEmpty.contact.captchaChallengeField=La question 'Captcha' est requise + +message.creditcard.invalid=Les informations de la carte de crédit sont requises +message.payment.declined=La transaction a été refusée +message.payment.error=Une erreur est survenue en essayant de compléter le paiement, si possible utiliser une autre méthode de paiement. +messages.error.creditcard.cvc=Le numéro de vérification inscrit sur la carte est invalide + +message.order.canprocess=La commande peut être complétée +message.name.required=Le nom de l'objet est reuis + +message.code.exist=Ce code existe déjà +message.name.exist=Ce nom existe déjà +message.invalid.amount=Montant invalide +message.region.exists=cette région existe déjà +message.region.null=La région ne peut être vide +message.invalid.price=Le format du prix est invalide +message.invalid.rate=Le format du taux est invalide +message.invalid.date=Format de la date invalide +message.maximumWeight.null=Poids maximum ne peut être vide +message.maximumWeight.invalid=Poids maximum doit être supérieur é 0 +message.unauthorized=Cette transaction ne peut être complétée +message.code.available=Ce code est disponible +message.image.height=Hauteur de l'image trop grande +message.image.width=Largeur de l'image trop grande +message.image.size=Image trop volumineuse +message.number.invalid=Doit être un nombre valide (ex 5) + +message.password.required=Un mot de passe est requis +message.password.repeat.required=Le mot de passe répété est requis +message.username.required=Le code d'usager est requis +message.username.notfound=Le code d'usager n'existe pas +message.price.cents=SVP entrer un maximum de 99 sous +message.security.cannotrevoke.superadmin=Le groupe Super Admin ne peut être révoqué +message.cannot.empty=ne peut être vide +message.password.different=Le nouveau mot de passe et le mot de passe répété doivent être identiques +message.password.invalid=Mot de passe invalide +message.password.length=Le mot de passe doit avoir au moins 6 caractéres +message.password.reset=Le mot de passe a été ré-initialisé +message.password.checkpassword.identical=Les deux mots de passe doivent être identiques +message.credentials.reset=Le données d'authentification ont été changées +message.address.enter=Entrez votre addresse + +message.security.caanotremovesuperadmin=Il n'est pas possible de détruire un usager super admin + +message.group.alerady.exists=Le groupe {0} existe déjà + +message.product.association=Cette entité est associée é un ou plusieurs produits. Veuillez détruire les associations et ré-essayer é nouveau. +message.notexist.customer=Le client n'existe pas + +message.optionset.optionassociationexists=Cette association d'options existe déjà +message.optionset.noassociation=Choisir une option et une valeur d'option + + +message.productoption.required=Un attribut/option de produit est requis +message.productoptionvalue.required=Une valeur d'attribut/option de produit est requis +message.product.language=Le produit n'a pas été configuré pour ce language. Veuillez éditer le produit et ajouter les informations pour cette langue. + +messages.error.creditcard=Les données de la carte de crédit sont invalides +messages.error.creditcard.number=Le numéro de carte de crédit est invalide +messages.error.creditcard.dateformat=La date d\\'expiration de la carte de crédit est invalide + +message.content.missing.agreement=Le contenu défini avec le code 'agreement' n'existe pas + +merchant.storeId.invalid=Le numéro de marchand est invalide +merchant.files.invalid=Veuillez fournir un ou plusieurs fichiers é charger +merchant.zone.invalid=L'état / province est requise + +NotEmpty.order.customerFirstName=Le prénom du client ne doit pas être vide +NotEmpty.order.customerLastName=Le nom de famille du client ne doit pas être vide +NotEmpty.order.customerStreetAddress=L'adresse du client ne doit pas être vide +NotEmpty.order.customerCity=La ville du client ne doit pas être vide +NotEmpty.order.customerPostCode=Le code postal du client ne doit pas être vide +NotEmpty.order.customerTelephone=Le numero de telephone du client ne doit pas être vide +Email.order.customerEmailAddress=Le email du client est invalide +NotEmpty.order.customerEmailAddress=Le email du client ne doit pas être vide + +NotEmpty.order.billingName=Le nom de facturation ne doit pas être vide +NotEmpty.order.billingStreetAddress=L'adresse de facturation ne doit pas être vide +NotEmpty.order.billingCity=La ville de facturation ne doit pas être vide +NotEmpty.order.billingState=La province de facturation ne doit pas être vide +NotEmpty.order.billingPostCode=Le code postal de facturation ne doit pas être vide + +NotEmpty.customer.FirstName=Le prenom du client ne doit pas être vide +NotEmpty.customer.LastName=Le nom de famille du client ne doit pas être vide +NotEmpty.customer.StreetAddress=L'adresse du client ne doit pas être vide +NotEmpty.customer.City=La ville du client ne doit pas être vide +NotEmpty.customer.PostCode=Le code postal du client ne doit pas être vide +NotEmpty.customer.Telephone=Le numero de telephone du client ne doit pas être vide +Email.customer.EmailAddress=Le email du client est invalide +NotEmpty.customer.EmailAddress=Le email du client ne doit pas être vide + +NotEmpty.customer.billingCompany=Le nom de compagnie ne doit pas être vide +NotEmpty.customer.billingFirstName=Le prénom de facturation ne doit pas être vide +NotEmpty.customer.billingLastName=Le nom de facturation ne doit pas être vide +NotEmpty.customer.billingStreetAddress=L'adresse de facturation ne doit pas être vide +NotEmpty.customer.billingCity=La ville de facturation ne doit pas être vide +NotEmpty.customer.billingState=La province de facturation ne doit pas être vide +NotEmpty.customer.billingCountry=Le pays de facturation ne doit pas être vide +NotEmpty.customer.billingPostCode=Le code postal de facturation ne doit pas être vide + +NotEmpty.customer.shippingCountry=Le pays de livraison ne doit pas être vide + +NotEmpty.taxClass.code=Le code de la classe de taxe est requis +NotEmpty.taxClass.title=Le nom de la classe de taxe est requis +message.taxclass.alreadyexist=Le code de classe existe déjà +NotEmpty.taxRate.code=Le code du taux de taxation est requis +NotEmpty.taxRate.unique.code=Le code du taux de taxation doit être unique +NotEmpty.taxRate.rateText=Le taux de taxation est requis +NotEmpty.taxRateDescription.name=Le nom du taux de taxation est requis +NotNull.taxRate.parent=Le taux de taxation parent doit être sélectionné + + +message.noshipping.configured=Aucune méthode de livraison configurée +message.noshipping=La livraison n'est pas disponible +message.noshippingerror=La livraison n'est pas disponible, veuillez valider le pays, la province ou l'état ainsi que le code postal de livraison + +message.login.duallogin=Le système ne supporte pas 2 authentifications sur le même fureteur + +User.resetPassword.resetSuccess=Le mot de passe a été changé. Vous recevrez votre nouveau mot de passe par courriel. +User.resetPassword.wrongSecurityQtn=La réponse à la question de sécurité est invalide +User.resetPassword.userNotFound=L'usager spécifié n`existe pas +User.resetPassword.Error=Une erreur s'est produite, contactez l'administrateur + +validaion.recaptcha.not.matched=Saisie du champs 'captcha' invalide +registration.username.not.empty=Veuillez fournir un nom d'usager +registration.password.not.empty=Veuillez fournir un mot de passe valide +registration.username.length.invalid=Le nom d\\'usager doit contenir au moins 6 caractères +registration.firstName.invalid=Le prénom est obligatoire +registration.lastName.invalid=Le nom est obligatoire +messages.invalid.email=Veuillez fournir une adress courriel valide +registration.username.already.exists = Ce nom d'usager existe déjà +registration.failed=Une erreur est survenue lors de l'enregistrement veuillez recommencer plus tard +currentpassword.not.empty=Veuillez fournir votre mot de passe actuel +newpassword.not.empty=Veuillez fournir un nouveau mot de passe valide +repeatpassword.not.empty=Veuillez répéter le nouveau mot de passe +message.invalidpassword=Mot de passe invalide + +error.code.99=Une erreur s\\'est produite en essayant de traîter le paiement (99) +message.sku.exists= le sku exist déjà pour un autre produit diff --git a/sm-shop/src/main/resources/bundles/payment.properties b/sm-shop/src/main/resources/bundles/payment.properties new file mode 100755 index 0000000000..68dbc1203d --- /dev/null +++ b/sm-shop/src/main/resources/bundles/payment.properties @@ -0,0 +1,61 @@ +payment.not.configured=No payment modules configured + + +payment.type.MONEYORDER=Money order +payment.type.PAYPAL=PayPal +payment.type.CREDITCARD=Credit card +payment.type.STRIPE=Credit card +payment.type.STRIPE3=Credit card +payment.type.BRAINTREE=Credit card + +label.payment.moneyorder.usemoneyorder=Use money order + +module.payment.paypal=PayPal +module.payment.beanstream=Beanstream +module.payment.authorizenet=Authorize Net +module.payment.moneyorder=Money order +module.payment.paypal-express-checkout=PayPal express checkout +module.payment.stripe=Stripe +module.payment.stripe3=Stripe V3 (3DSecure support - requires Webhook) +module.payment.braintree=Braintree + + +module.payment.transactiontype=Transaction type +module.payment.transactiontype.preauth=Pre-authorization +module.payment.transactiontype.capture=Capture +module.payment.transactiontype.sale=Sale +module.payment.transactiontype.refund=Refund + +#PayPal +module.payment.paypal-express-checkout.userid=PayPal API user name +module.payment.paypal-express-checkout.apikey=PayPal API password +module.payment.paypal-express-checkout.signature=PayPal API signature +module.payment.paypal-express-checkout.applicationid=PayPal application id +module.payment.paypal-express-checkout.note=Follow the instructions here to create you PayPal API user name, password and signature (https://developer.paypal.com/docs/classic/api/apiCredentials/#creating-classic-api-credentials) + + + +#paypal rest +module,payment.paypal.clientId=PayPal clientId +module,payment.paypal.secret=PayPal secret +module.payment.paypal.note=Create a PayPal seller account (www.paypal.com). Once completed, login to PayPal developer website (https://developer.paypal.com/webapps/developer/index) using your PayPal seller credentials. Click Applications on the upper nav bar to access the My Applications page. Click on Create App button, this action will provide your client id and secret keys. +module.payment.paypal.message.clientId=PayPal clientId is required +module.payment.paypal.message.secret=PayPal secret is required + +module.payment.paypal.message.identifier=PayPal API user name required +module.payment.paypal.message.api=PayPal API user name required +module.payment.paypal.message.password=PayPal API password required +module.payment.paypal.message.signature=PayPal API signature required + +#Beanstream +module.payment.beanstream.merchantid=Merchant id +module.payment.beanstream.username=User name +module.payment.beanstream.password=Password + +module.payment.beanstream.message.merchantid=Merchant id required +module.payment.beanstream.message.username=Username is required +module.payment.beanstream.message.password=Password is required + +#Moneyorder +module.payment.moneyorder.adress=Cheque to be made to this address +module.payment.moneyorder.message.address=Address is required \ No newline at end of file diff --git a/sm-shop/src/main/resources/bundles/payment_fr.properties b/sm-shop/src/main/resources/bundles/payment_fr.properties new file mode 100755 index 0000000000..febf01e2a2 --- /dev/null +++ b/sm-shop/src/main/resources/bundles/payment_fr.properties @@ -0,0 +1,55 @@ +payment.not.configured=Aucun module de paiement configuré + +payment.type.MONEYORDER=Chèque +payment.type.PayPal=PayPal +payment.type.CREDITCARD=Carte de crédit +payment.type.STRIPE=Carte de crédit +payment.type.BRAINTREE=Carte de crédit + +label.payment.moneyorder.usemoneyorder=Utiliser les chèques + + +module.payment.PayPal=PayPal +module.payment.beanstream=Beanstream +module.payment.authorizenet=Authorize Net +module.payment.moneyorder=Chèque +module.payment.paypal-express-checkout=PayPal express checkout +module.payment.stripe=Stripe +module.payment.braintree=Braintree + +module.payment.transactiontype=Type de transaction +module.payment.transactiontype.preauth=Pré-authorization +module.payment.transactiontype.capture=Capture +module.payment.transactiontype.sale=Vente +module.payment.transactiontype.refund=Remboursement + +#PayPal +module.payment.paypal-express-checkout.userid=Usager PayPal API +module.payment.paypal-express-checkout.apikey=Mot de pass APImodule.payment +module.payment.paypal-express-checkout.signature=PayPal API signature +module.payment.paypal-express-checkout.applicationid=PayPal identifiant de l'application +module.payment.paypal-express-checkout.note=Suivez les instructions afin de créer votre usager, mot de passe et signature PayPal (https://developer.paypal.com/docs/classic/api/apiCredentials/#creating-classic-api-credentials) + +module.payment.paypal.clientId=PayPal clientId +module.payment.paypal.secret=PayPal secret +module.payment.paypal.note=Créez un compte PayPal (www.PayPal.com). Une fois terminé, connectez-vous au site PayPal pour développeur (https://developer.paypal.com/webapps/developer/index) en utilisant votre compte PayPal. Cliquez sur Applications sur la barre de navigation supérieure pour accéder à la page Mes applications. Cliquez sur le bouton Créer une Application, cette action vous fournira votre numéro de client et la clé secrète. +module.payment.paypal.message.clientId=PayPal clientId est requis +module.payment.paypal.message.secret=PayPal secret est requis + +module.payment.paypal.message.identifier=Usager API PayPal requis +module.payment.paypal.message.api=Clée API PayPal requise +module.payment.paypal.message.password=PayPal API mot de passe requis +module.payment.paypal.message.signature=PayPal API signature requise + +#Beanstream +module.payment.beanstream.merchantid=Identifiant marchand +module.payment.beanstream.username=Nom d'usager +module.payment.beanstream.password=Mot de passe + +module.payment.beanstream.message.merchantid=Identifiant marchand requis +module.payment.beanstream.message.username=Nom d'usager requis +module.payment.beanstream.message.password=Mot de passe requis + +#Moneyorder +module.payment.moneyorder.adress=Le chèque doit être fait à cette adresse +module.payment.moneyorder.message.address=L'adresse est requise \ No newline at end of file diff --git a/sm-shop/src/main/resources/bundles/shipping.properties b/sm-shop/src/main/resources/bundles/shipping.properties new file mode 100755 index 0000000000..d4b142039d --- /dev/null +++ b/sm-shop/src/main/resources/bundles/shipping.properties @@ -0,0 +1,145 @@ +NO_SHIPPING_MODULE_CONFIGURED=No shipping module configured + +module.shipping.canadapost=Canada Post +module.shipping.ups=UPS +module.shipping.usps=United States Postal Service +module.shipping.fedex=Fedex +module.shipping.weightBased=Weight based shipping price +module.shipping.customQuotesRules=Shipping by {0} +module.shipping.storePickUp=Store pick up +module.shipping.priceByDistance=Shipping by {0} + +module.shipping.storePickUp.note=This option lets you reserve your order items through the online system and pick up your order by yourself at the store. This option is also offered when no other shipping option is available for your region. + +#custom +module.shipping.customQuotesRules.title=Create your own shipping quotes rules +module.shipping.customQuotesRules.text=Use the rule system to create your own shipping rate decision table. The custom shipping rate decision table can be edited in sm-core/src/main/resources/rules/shipping-custom-rules.xls + +#custom +module.shipping.priceByDistance.title=Create your own shipping quote based on distance +module.shipping.priceByDistance.text=Set your shipping price (by kilometer). Requires the pre-processor distance calculator. + +module.shipping.canada=Canada +module.shipping.usa=United states +module.shipping.international=International + + + +#Canada Post +module.shipping.canadapost.identifier=Canada Post identifier (CPC number) +module.shipping.canadapost.username=Canada Post user name (first part of the API key before semi column) +module.shipping.canadapost.password=Canada Post password (second part of the API key after semi column) +module.shipping.canadapost.apikey=Canada Post API key +module.shipping.canadapost.packages=Package type +module.shipping.canadapost.services=Services to be rated +module.shipping.canadapost.message.identifier=Canada Post identifier required +module.shipping.canadapost.message.username=Canada Post user name required +module.shipping.canadapost.message.password=Canada Post password required +module.shipping.canadapost.message.apikey=Canada Post API key required + +module.shipping.canadapost.DOM.RP=Regular Parcel +module.shipping.canadapost.DOM.EP=Expedited Parcel +module.shipping.canadapost.DOM.XP=Xpresspost +module.shipping.canadapost.DOM.XP.CERT=Xpresspost Certified +module.shipping.canadapost.DOM.PC=Priority +module.shipping.canadapost.DOM.DT=Delivered Tonight +module.shipping.canadapost.DOM.LIB=Library Books + +module.shipping.canadapost.USA.EP=Expedited Parcel USA +module.shipping.canadapost.USA.PW.ENV=Priority Worldwide Envelope USA +module.shipping.canadapost.USA.PW.PAK=Priority Worldwide pak USA +module.shipping.canadapost.USA.PW.PARCEL=Priority Worldwide Parcel USA +module.shipping.canadapost.USA.SP.AIR=Small Packet USA Air +module.shipping.canadapost.USA.TP=Tracked Packet - USA +module.shipping.canadapost.USA.TP.LVM=Tracked Packet - USA - (LVM - large volume mailers) +module.shipping.canadapost.USA.XP=Xpresspost USA + + +module.shipping.canadapost.INT.XP=Xpresspost International +module.shipping.canadapost.INT.IP.AIR=International Parcel Air +module.shipping.canadapost.INT.IP.SURF=International Parcel Surface +module.shipping.canadapost.INT.PW.ENV=Priority Worldwide Envelope International +module.shipping.canadapost.INT.PW.PAK=Priority Worldwide pak International +module.shipping.canadapost.INT.PW.PARCEL=Priority Worldwide parcel International +module.shipping.canadapost.INT.SP.AIR=Small Packet International Air +module.shipping.canadapost.INT.SP.SURF=Small Packet International Surface +module.shipping.canadapost.INT.TP=Tracked Packet - International + + +#USPS +module.shipping.usps.identifier=USPS account identifier +module.shipping.usps.packages=Package type +module.shipping.usps.shippingmethods=Select up to 3 shipping methods +module.shipping.usps.message.identifier=USPS account identifier required +module.shipping.usps.message.packages=You must select one package type + + +module.shipping.usps.package.01=Variable +module.shipping.usps.package.02=Flat Rate Box +module.shipping.usps.package.03=Flat Rate Envelope +module.shipping.usps.package.04=Rectangular +module.shipping.usps.package.05=Non Rectangular +module.shipping.usps.package.06=LG Flat Rate Box + +module.shipping.usps.package.07=Envelope +module.shipping.usps.package.08=Package + +module.shipping.usps.method.01=First-Class Mail +module.shipping.usps.method.02=Priority Mail +module.shipping.usps.method.03=Express Mail +module.shipping.usps.method.04=Express SH +module.shipping.usps.method.05=Express HFP +module.shipping.usps.method.06=BPM +module.shipping.usps.method.07=Parcel Post + +#UPS +module.shipping.ups.identifier=UPS access key +module.shipping.ups.userid=User ID +module.shipping.ups.password=Password +module.shipping.ups.packages=Package type +module.shipping.ups.shippingmethods=Select a shipping method +module.shipping.ups.message.identifier=UPS account identifier required +module.shipping.ups.message.packages=You must select one package type + + + +module.shipping.ups.package.02=Customer Package +module.shipping.ups.packagel.01=UPS Letter +module.shipping.ups.package.03=UPS Tube +module.shipping.ups.package.04=UPS Pak +module.shipping.ups.package.21=UPS Express Box +module.shipping.ups.package.24=UPS 25kg Box +module.shipping.ups.package.10=UPS 10kg box +module.shipping.ups.package.25=Unknown + + + + +module.shipping.ups.method.01=UPS Next Day Air +module.shipping.ups.method.02=UPS Second Day Air +module.shipping.ups.method.03=UPS Ground +module.shipping.ups.method.07=UPS Worldwide Express +module.shipping.ups.method.08=UPS Worldwide Expedited +module.shipping.ups.method.11=UPS Standard +module.shipping.ups.method.12=UPS Three-Day Select +module.shipping.ups.method.13=UPS Next Day Air Saver +module.shipping.ups.method.14=UPS Next Day Air Early A.M. +module.shipping.ups.method.54=UPS Worldwide Express Plus +module.shipping.ups.method.59=UPS Second Day Air A.M. +module.shipping.ups.method.65=UPS Saver + +#module.shipping.ups.method.68=UPS Express +#module.shipping.ups.method.69=UPS Worldwide Expedited +#module.shipping.ups.method.70=UPS Standard +#module.shipping.ups.method.71=UPS Worldwide Express Plus +#module.shipping.ups.method.72=UPS Saver +module.shipping.ups.method=UPS shipping methods +module.shipping.ups.method.select=Select a specific UPS shipping method +module.shipping.ups.method.unselect=Let UPS propose all available shipping methods + + +#store pick up +module.shipping.storePickUp.address=Pick up address that will be displayed to the client +module.shipping.storePickUp.address.message=Pick up address is a required field +module.shipping.storePickUp.price=Price for store pick up in numeric format (usually 0) +module.shipping.storePickUp.price.message=Price for store pick up is required (in numeric format) \ No newline at end of file diff --git a/sm-shop/src/main/resources/bundles/shipping_fr.properties b/sm-shop/src/main/resources/bundles/shipping_fr.properties new file mode 100755 index 0000000000..c12aec9fea --- /dev/null +++ b/sm-shop/src/main/resources/bundles/shipping_fr.properties @@ -0,0 +1,96 @@ +NO_SHIPPING_MODULE_CONFIGURED=Aucun module de livraison configuré + +module.shipping.canadapost=Postes Canada +module.shipping.ups=UPS +module.shipping.usps=United States Postal Service +module.shipping.fedex=Fedex +module.shipping.weightBased=Prix basé sur le poids +module.shipping.customQuotesRules=Livraison par {0} +module.shipping.storePickUp=Ramassage en magasin +module.shipping.priceByDistance=Livraison par {0} + +module.shipping.storePickUp.note=Cette option vous permet de réserver votre commande via le système web et de ramasser par vous même l'item ou les items en magasin. Cette option est également offerte lorsque aucune autre option de livraison est disponible dans votre secteur. + +#custom +module.shipping.customQuotesRules.title=Vous pouvez produire vos propre règles de coûts d'expédition +module.shipping.customQuotesRules.text=Utilisez le système de règles d'affaires afin de créer votre propre table de décision des coûts d'expédition. Le fichier de règles d'affaires des coûts d'expédition peut être édité sous sm-core/src/main/resources/rules/shipping-custom-rules.xls + +#custom +module.shipping.priceByDistance.title=Vous pouvez produire vos propre règles de coûts d'expédition basées sur la distance +module.shipping.priceByDistance.text=Calcul du prix de livraison sur un prix fixe par kilomètre. Requiert le pré-processeur permettant de calculer la distance de livraison. + +module.shipping.canada=Canada +module.shipping.usa=États-Unis +module.shipping.international=International + +#Canada Post +module.shipping.canadapost.identifier=Identifiant Postes Canada (numéro CPC) +module.shipping.canadapost.username=Nom d'usager Postes Canada (première partie de la clé API avant les 2 points :) +module.shipping.canadapost.password=Mot de passe Postes Canada (deuxième partie de la clé API après les 2 points :) +module.shipping.canadapost.apikey=Clé API Postes Canada +module.shipping.canadapost.services=Services de postage à calculer +module.shipping.canadapost.packages=Type d'emballage +module.shipping.canadapost.message.identifier=Identifiant Postes Canada requis +module.shipping.canadapost.message.packages=Au moins un type d'emballage +module.shipping.canadapost.message.apikey=Clé API requise + +module.shipping.canadapost.DOM.RP=Colis standard +module.shipping.canadapost.DOM.EP=Colis accélérés +module.shipping.canadapost.DOM.XP=Xpresspost +module.shipping.canadapost.DOM.XP.CERT=Xpresspost certifié +module.shipping.canadapost.DOM.PC=Priorité +module.shipping.canadapost.DOM.DT=Service Livré ce soir +module.shipping.canadapost.DOM.LIB=Livres de bibliothèque + +module.shipping.canadapost.USA.EP=Colis accélérés É.-U. +module.shipping.canadapost.USA.PW.ENV=Enveloppe Priorité Mondial – É.-U. +module.shipping.canadapost.USA.PW.PAK=Paquet Priorité Mondial – É.-U. +module.shipping.canadapost.USA.PW.PARCEL=Colis Priorité Mondial – É.-U. +module.shipping.canadapost.USA.SP.AIR=Petits paquets-avion à destination des É.-U. +module.shipping.canadapost.USA.TP=Paquet repérable – É.-U. +module.shipping.canadapost.USA.TP.LVM=Paquet repérable – É.-U. (GEC - gros expéditeur de courrier) +module.shipping.canadapost.USA.XP=Xpresspost É.-U. + +module.shipping.canadapost.INT.XP=Xpresspost International +module.shipping.canadapost.INT.IP.AIR=Colis-avion du régime international +module.shipping.canadapost.INT.IP.SURF=Colis de surface du régime international +module.shipping.canadapost.INT.PW.ENV=Enveloppe Priorité Mondial – International +module.shipping.canadapost.INT.PW.PAK=Paquet Priorité Mondial – International +module.shipping.canadapost.INT.PW.PARCEL=Colis Prioritié Mondial – International +module.shipping.canadapost.INT.SP.AIR=Petits paquets-avion du régime international +module.shipping.canadapost.INT.SP.SURF=Petits paquets de surface du régime international +module.shipping.canadapost.INT.TP=Paquet repérable – International + +#USPS +module.shipping.usps.identifier=Numéro de compte USPS +module.shipping.usps.packages=Type d'emballage +module.shipping.usps.shippingmethods=Choisir jusqu'a 3 méthodes d'expédition +module.shipping.usps.message.identifier=Identifiant USPS requis +module.shipping.usps.message.packages=Vous devez choisir un type d'emballage + + +module.shipping.usps.package.01=Variable +module.shipping.usps.package.02=Flat Rate Box +module.shipping.usps.package.03=Flat Rate Envelope +module.shipping.usps.package.04=Rectangular +module.shipping.usps.package.05=Non Rectangular +module.shipping.usps.package.06=LG Flat Rate Box + +module.shipping.usps.package.07=Envelope +module.shipping.usps.package.08=Package + +module.shipping.usps.method.01=First-Class Mail +module.shipping.usps.method.02=Priority Mail +module.shipping.usps.method.03=Express Mail +module.shipping.usps.method.04=Express SH +module.shipping.usps.method.05=Express HFP +module.shipping.usps.method.06=BPM +module.shipping.usps.method.07=Parcel Post +module.shipping.canadapost.packages.package=Paquet +module.shipping.canadapost.packages.envelope=Enveloppe + +#store pick up +module.shipping.storePickUp.address=Adresse de ramassage affichée au client +module.shipping.storePickUp.address.message=L'Adresse de ramassage est un champ requis +module.shipping.storePickUp.price=Prix de l'option de ramassage en magasin (normalement 0) +module.shipping.storePickUp.price.message=Le prix de l'option de ramassage est requis (en format numérique) diff --git a/sm-shop/src/main/resources/bundles/shopizer.properties b/sm-shop/src/main/resources/bundles/shopizer.properties new file mode 100755 index 0000000000..10cbce7dc5 --- /dev/null +++ b/sm-shop/src/main/resources/bundles/shopizer.properties @@ -0,0 +1,793 @@ +label.quantity=Quantity + +label.defaultlanguage=Default language +label.defaultSelection=Default selection +lang.en=English +lang.fr=French +lang.ru=Russian +lang.es=Spanish +lang.ar=Arabic +lang.pt-BR=Portuguese (BR) + +label.shop=Shop +label.entity.id=Id +label.entity.name=Name +label.entity.code=Code +label.entity.visible=Visible +label.entity.enabled=Enabled +label.entity.featured=Featured +label.entity.active=Active +label.entity.public=Public +label.entity.details=Details +label.entity.type=Type +label.entity.remove.confirm=Do you really want to remove this entity? +label.entity.setAsDefault.confirm=Do you really want to set this entity as default? +label.entity.order=Order +label.entity.status=Status +label.generic.all=All +label.generic.email=Email address +label.generic.address=Address +label.generic.city=City +label.generic.country=Country +label.generic.price=Price +label.generic.phone=Phone number +label.generic.back=Back +label.generic.setAsDefault=Set as default +label.generic.country.code=Country code +label.generic.stateprovince=State / province +label.generic.postalcode=Postal code +label.generic.item=item +label.generic.item.title=Item +label.generic.items=items +label.generic.displayonly=Display only +label.generic.url=URL +label.generic.sortby=Sort by +label.generic.default=Default +label.generic.name=Name +label.generic.next=Next +label.generic.genre=Genre +label.generic.male=Male +label.generic.female=Female +label.generic.register=Register +label.generic.youropinion=Your opinion +label.generic.comments=Comments +label.generic.subject=Subject +label.generic.minimum=Minimum +label.generic.maximum=Maximum +label.generic.pictures=Pictures +label.generic.videos=Videos +label.generic.imageType=Media type +label.generic.today=Today + +label.generic.welcome=Welcome +label.generic.weightunit.LB=Pounds +label.generic.weightunit.KG=Kilograms +label.generic.language=Language +label.generic.search=Search + +label.generic.sizeunit.CM=Centimeters +label.generic.sizeunit.IN=Inches +label.generic.remove=Remove +label.generic.yes=Yes +label.generic.no=No +label.generic.alphanumeric=Alphanumeric +label.generic.add=Add +label.generic.username=User name +label.generic.edit=Edit +label.generic.print=Print + +label.generic.environment=Environment +label.generic.providedby=Powered by + +label.generic.title=Title +label.generic.keywords=Keywords +label.generic.amount=Amount + +label.generic.changepassword=Change password + +label.generic.confirm=Please confirm! +label.generic.firstname=First name +label.generic.lastname=Last name +label.generic.streetaddress=Street address +label.generic.postalcode=Postal code +label.generic.city=City +label.generic.country=Country +label.generic.hi=Hi +label.generic.send=Send +label.generic.rebate=Rebate + +label.soldout=Sold out + +#merchant store +label.store.information.title=Information +label.store.title=Merchant Store +label.store.information=Store information +label.storeadministration=Store administration +label.storeadministrator=Store administrator +label.storename=Store Name +label.storecode=Unique Store Code +label.currency=Currency +label.bgcolorcode=Background Color +label.storelogo=Store Logo +label.storebanner=Store Banner +label.storephone=Store Phone +label.accepteddomains=Accepted Domains +label.storeaddress=Store Address +label.storecity=Store City +label.storepostalcode=Store Postal Code +label.storecountry=Store Country +label.storezone=Store State / Province +label.supportedlanguages=Supported languages +label.storeemailaddress=Store email address +label.storesetup=Store setup +label.store.template=Theme +label.store.baseurl=Store base url (domain) +label.store.inbusinesssince=Web site operating since +label.changepasswordrequest = Change password request +label.store.weightunit=Weight units +label.store.sizeunits=Size units +label.store.list=Stores +label.store.useCache=Use cache +label.store.currency.format=National currency format +label.store.currency.format.help=National currency format ex $1,345.79 or International currency format ex USD1,345.79 + +label.store.displaycontactussection=Display contact us page +label.store.displaystoreaddress=Display store address +label.store.displaysearchbox=Display search box +label.store.displaypagesmenu=Display 'Page' menu +label.store.testmode=Test mode (hide category and product details) +label.store.debugmode=Debug mode (add additional debug) +label.store.allowPurchaseItems=Allow purchase items +label.store.displayaddtocartfeatured=Allow add to cart on featured items +label.store.tofindus=Where to find us + +label.storefront.landingpage=Landing page information +label.storefront.storetext=Landing page main text +label.storefront.metatags.keywords=Meta tags keywords +label.storefront.metatags.description=Meta tags description +label.storefront.landingpage.title=Landing page title + +#user +label.profile.title=User profile +label.my.profile=My profile +label.profile.lastaccess=Last access +label.register.personal.information=Personal information +label.register.signin.information=Sign-in information +label.register.createaccount=Create an account + +#search +label.search.searchQuery=Search query +label.search.items.found=item(s) found + + +label.generic.password=Password +label.generic.repeatpassword=Repeat password +label.generic.newpassword=New password +label.generic.newpassword.repeat=Repeat new password + +label.store.question=Have a question? + +security.question.1=What was the color of your first car? +security.question.2=In what city were you born? +security.question.3=What was the name of your first pet? +security.question.4=What is your preferred musical genre? +security.question.5=Who was your childhood hero? +security.question.6=In what city or town was your first job? +security.question.7=Where were you when you had your first kiss? +security.question.8=In which city did you met your spouse/significant other? +security.question.9=What was your childhood nickname? + + +security.questions.differentmessages=Please select 3 different questions + +security.question1=Question 1 +security.question2=Question 2 +security.question3=Question 3 +security.answer.question1.message=Please answer to security question 1 +security.answer.question2.message=Please answer to security question 2 +security.answer.question3.message=Please answer to security question 3 + + +security.group.description.SUPERADMIN=A single user can be superadmin. The user admin is created by default as the superadmin user. This user can do everything in the system and is the only one who can manage stores. +security.group.description.ADMIN=An admin user is a user with most privileges for a store administration. An admin user can do everything as a store manager and can also create users with more restricted access. +security.group.description.ADMIN_CATALOGUE=A user part of that group can create products, categories and featured items. +security.group.description.ADMIN_STORE=A user part of that group can manage the store he is assigned too. He will be able to change the branding and modify anything under store menu. This group gives also access to the shipping and payment configuration +security.group.description.ADMIN_ORDER=A user part of that group can manage orders, search for orders, modify customer information, apply refund to an order. +security.group.description.ADMIN_CONTENT=A user assigned to that group will be able to manage the site dynamic and static content, add images, aand files to the system. + +label.security.loggedinas=You are logged in as +label.security.nologinacces.store=We can't display store logon box + +#customer +label.customer.registered=Registered customer +label.customer.new=New customer +label.customer.registered.signinemail=If you have an account, sign in with your email address +label.customer.signin.social=Make it easier and sign in with your {0} account! +label.customer.signin.social.system=Sign in with {0} +label.customer.faster=Creating an account has many benefits: check out faster, keep more than one address, track orders and more. +label.customer.myaccount=My Account +label.customer.contactus=Contact us +label.customer.list=Customer list +label.customer.name=Customer name +label.customer.lastname=Customer last name +label.customer.firstname=Customer first name +label.customer.id=Customer id +label.customer.companyname=Company name +label.customer.email=Customer email address +label.customer.streetaddress=Customer street address +label.customer.suburb=Customer suburb +label.customer.postalcode=Customer postal code +label.customer.telephone=Customer phone +label.customer.city=Customer city +label.customer.zone=Customer state / province +label.customer.country=Customer country +label.customer.registered=Registered customer +label.customer.editcustomer=Edit Customer +label.customer.createcustomer=Create Customer +label.customer.order.date= Order date +label.customer.order.agreement=I agree with the terms and conditions +label.customer.order.agreement.title=Terms and conditions +label.customer.options.edit=Edit option +label.customer.option=Customer option +label.customer.option.value=Customer option value + +label.customer.billinginformation=Billing information +label.customer.shippinginformation=Shipping information +label.customer.shippingaddress=Shipping Address +label.customer.billingaddress=Billing Address +label.customer.billingshipping=Billing & shipping information + +label.customer.edit.billingaddress=Edit Billing Address +label.customer.edit.shippinginformation=Edit Shipping information + +label.customer.billing.company=Billing company +label.customer.billing.streetaddress=Billing street address +label.customer.billing.suburb=Billing suburb +label.customer.billing.postalcode=Billing postal code +label.customer.billing.city=Billing city +label.customer.billing.zone=Billing state / province +label.customer.billing.country=Billing country +label.customer.billing.firstname=Billing first name +label.customer.billing.lastname=Billing last name +label.customer.billing.name=Billing name + +label.customer.shipping.company=Shipping company +label.customer.shipping.streetaddress=Shipping street address +label.customer.shipping.suburb=Shipping suburb +label.customer.shipping.postalcode=Shipping postal code +label.customer.shipping.city=Shipping city +label.customer.shipping.zone=Shipping state / province +label.customer.shipping.country=Shipping country +label.customer.shipping.firstname=Shipping first name +label.customer.shipping.lastname=Shipping last name +label.customer.shipping.name=Shipping name +label.customer.shipping.shipaddress=Ship to this address +label.customer.shipping.shipdifferentaddress=Ship to a different address? + +label.customer.confirmshippingaddress=Shipping address confirmation + +label.customer.optionv.edit=Edit option +label.customer.option.name=Option name +label.customer.option.code=Option code +label.customer.option.type=Display type + +label.customer.optionvalue.edit=Edit option value +label.customer.optionvalue.name=Option value name +label.customer.optionvalue.code=Option value code + +label.customer.displaycustomersection=Display customer section +label.customer.accessportal=You can access the customer section using the following url +label.customer.accessnow=Access now! + +label.customer.resetpasswor.confirm=Are you sure you want to reset the customer password? +label.customer.moredetails=More details! +label.order.editcustomer=Edit customer +label.order.displayagreement=Display customer terms and policy agreement in order page +label.order.notes=Order notes +label.order.notes.eg=Notes for the order or delivery + + +label.customer.currentpassword=Current password +label.customer.newpassword=New password +label.customer.repeatpassword=Repeat password + +label.customer.createaccount=Create an account? +label.customer.accountpassword=Account password +label.customer.createaccount.text=Create an account by entering the information below. If you are a returning customer please login using the link at the top of the page. + +#permission +label.permissions.title=Permissions +label.permission.editpermission=Edit permission +label.permission.createpermission=Create permission +label.permission.name=Permission name + +#groups +label.groups.title=Groups +label.group.editgroup=Edit group +label.group.creategroup=Create group +label.group.root=Root +label.group.groupId=Group Id + +#category +label.category.title=Category title +label.category.highlight=Short category highlight +label.categories.title=Categories +label.categories.hierarchy.title=Categories hierarchy +label.category.root=Root +label.productedit.categoryname=Category name +label.productedit.choosecategory=Choose a category +label.category.categogydetails=Category details +label.category.editcategory=Edit category +label.category.movecategory=Move category +label.category.moveundercategory=Move under category +label.category.createcategory=Create category +label.category.code=Category code +label.category.categoryvisible=Category visible +label.category.categorydescription=Category description +label.category.parentcategory=Parent category +label.category.hierarchy.text=Drag categories to re-organize the hierarchy +label.category.maincategories=Main categories + +#manufacturer +label.manufacturer.brand=Brands +label.manufacturer.edit=Edit manufacturer +label.manufacturer.create=Create a manufacturer +label.manufactureredit.manufacturername=Manufacturer name +label.manufactureredit.manufacturertitle=Manufacturer title +label.manufactureredit.manufacturerurl=URL +label.manufactureredit.manufacturerurlclicked=URL clicked +label.manufactureredit.manufacturerdescription=Manufacturer description +label.manufacturer.image=Image +label.manufactureredit.manufacturerorder=Order + + +#product +label.product.create=Create a product +label.product.edit=Edit product +label.sefurl=Search engine friendly url +label.metatags.description = (Meta tags) Description +label.metatags.keywords = (Meta tags) Keywords +label.product.sku=Sku +label.product.refsku=Reference system identifier +label.product.available=Available +label.productedit.productname=Product name +label.productedit.producthl=Short product highlight +label.productedit.productdesc=Product description +label.product.title=Product title +label.product.price=Product price +label.product.price.code=Product price code +label.product.preorder=Pre-order +label.product.price.name=Product price name +label.product.price.priceAppender=Product price appender +label.product.price.default=Default product price +label.product.price.special=Special price +label.product.price.special.startdate=Special start date +label.product.price.special.enddate=Special end date +label.taxclass =Tax class +label.product.ordermax=Quantity order max +label.product.ordermin=Quantity order min +label.product.visible=Product visible +label.product.status=Status +label.product.weight=Weight +label.product.height=Height +label.product.length=Length +label.product.width=Width +label.product.image=Image +label.product.uploadfile=Upload file +label.product.details=Product details +label.product.prices=Product prices +label.product.attributes=Product options / attributes +label.product.attribute=Option / attribute +label.product.attribute.default=Default option +label.product.attribute.required=Required option +label.product.attribute.display=Use attribute for display only +label.product.attribute.otherweight=Additional weight +label.product.attribute.option.name=Option / attribute name +label.product.attribute.value=Attribute value +label.product.attribute.specifications=Specifications +label.product.price.create=Create product price +label.product.attribute.create=Create product option / attribute +label.product.category.association=Associate product in categories +label.product.customer.reviews=Customer review(s) +label.product.reviews=Reviews +label.product.reviews.rating=Rating +label.product.reviews.write=Write a review +label.product.reviews.logon.write=You have to be authenticated to write a review +label.product.reviews.evaluated=You have evaluated this product +label.product.featured.meassage=To add a product to the featured items list drag the desired product from the list of available products to the featured items box. +label.product.group.meassage=To add a product to the product group list drag the desired product from the list of available products to the product group box. +label.product.related.title=Related items +label.product.related.meassage=To add a product to the related items list drag the desired product from the list of available products to the related items box. +label.product.createsimilar=Create similar product +label.product.configure=Product definition +label.product.specification=Specification +label.product.digitalproduct=Digital product +label.product.specials=Specials +label.product.brand=Brand +label.product.code=Product code +label.product.nomoreitems=No more items available +label.product.moreitems=Display more items +label.product.searchkeywords=Search keywords +label.product.shipeable=Product will be shipped +label.product.outofstock=Out of stock +label.product.defaultImage.message=When selecting default, this image will be the image displayed in the product page + +#options +label.product.productoptions.edit.title=Edit product option +label.product.productoptions.create.title=Create product option +label.product.productoptions.title=Product option +label.product.productoptions.name=Option name +label.product.productoptions.price=Option price +label.product.productoptions.comments=Option comments +label.product.productoptions.type=Option type +label.product.productoptions.list=Options list + +label.product.productoption.type.text=Text +label.product.productoption.type.radio=Radio +label.product.productoption.type.select=Select +label.product.productoption.type.checkbox=Checkbox + +label.product.option.displayonly=Option for display only +label.product.option.code=Option code +label.product.option.codehelp=Option code is required for querying products by attributes + +#options values +label.product.productoptionsvalues.title=Product option values +label.product.productoptionsvalues.list=Product options values list +label.product.productoptiosvalue.title=Product option value +label.product.productoptionvalue.edit.title=Edit product option value +label.product.productoptionvalue.create.title=Create product option value +label.product.productoptionvalue=Option value image + +label.product.customGroup.title=Product group +label.product.customgroup.add=Add custom product group +label.product.customgroup.code=Custom product group code (must be unique) + +label.product.rate=Rate product +label.product.clickrate=Product rating (click on the stars to activate rating) + +#content Images - Files +label.page=Page +label.contentImages.store=Merchant Store +label.content.images=Images library +label.content.files=Files library +label.content.pages=Content pages +label.content.pages.manage.content=Manage content pages +label.content.manage.content=Manage content +label.content.pages.page.name=Page name +label.content.pages.page.content=Page content +label.content.boxes=Content boxes +label.content.boxes.position=Box position +label.content.boxes.name=Box name +label.content.sections=Content sections +label.content.friendlyurl=Friendly url +label.content.metatag.description=Description metatag +label.content.page.displaymainmenu=Display this page in main menu + +#shipping +label.shipping.title=Shipping configuration +label.shipping.national=National +label.shipping.international=International +label.shipping.mode=Shipping mode +label.shipping.methods=Shipping methods +label.shipping.countries=Ship to countries +label.shipping.options=Shipping options +label.shipping.taxonshipping=Apply tax on shipping +label.shipping.freeshipping=Apply free shipping +label.shipping.freeshippingamount=Free shipping on order amount over +label.shipping.handlingfees=Handling fees +label.shipping.packaging.title=Packaging information +label.shipping.packaging.individual=Items will be shipped individually +label.shipping.packaging.boxes=Items will be combined and shipped in a box +label.shipping.packaging.box.height=Box height +label.shipping.packaging.box.length=Box length +label.shipping.packaging.box.width=Box width +label.shipping.packaging.box.weight=Box weight +label.shipping.packaging.box.maxweight=Maximum weight in box +label.shipping.packaging.box.maxitems=Maximum items in a box +label.shipping.addregion=Add region +label.shipping.region=Region +label.shipping.allquotes=Display all shipping quotes +label.shipping.leastexpensivequotes=Display least expensive shipping quotes +label.shipping.moreexpensivequotes=Display highest expensive shipping quotes +label.message.region.available=Region available +label.message.region.exist=Region already exists +label.shipping.maximumWeight=Maximum weight +label.shipping.shippingaddress=Shipping address +label.shipping.billingaddress=Billing address +label.message.maximumWeight.exist=Maximum weight already exists +label.shipping.fees=Shipping fees +label.shipping.freeshipping=Free shipping! +label.shipping.freeshipping.over=Free shipping for orders over +label.shipping.freeshippingandhandling=Free shipping and handling +label.shipping.origin.title=Shipping address origin +label.shipping.origin.description=Shipping origin will help calculate the distance between the origin to the destination of the delivery. If the origin is not set the system will use the merchant store address as the shipping origin. + +#order +label.order.title=Orders +label.order.total=Total +label.order.totals=Totals +label.order.date=Order date +label.order.module=Payment module +label.order.paymentmode=Payment mode +label.order.shippingmethod=Shipping mode +label.order.refund=Apply refund +label.order.capture=Capture transaction +label.order.item=Item +label.order.price=Price +label.order.sendinvoice=Send email invoice +label.order.printinvoice=Print invoice +label.order.packing=Print packing slip +label.order.updatestatus=Send order status email +label.order.downloademail=Send download email +label.order.history=History +label.order.recent=Recent orders +label.order.pastorders=Past orders +label.order.summary=Order summary +label.order.details=Order details +label.order.PROCESSING=Processing +label.order.ORDERED=Ordered +label.order.PAID=Paid +label.order.SHIPPED=Delivered +label.order.PREPARED=Prepared +label.order.REFUNDED=Refunded +label.order.DELIVERED=Delivered +label.order.CANCELED=Canceled +refund=Refund + +order.total.subtotal=Subtotal +order.total.total=Total +order.total.shipping=Shipping +order.total.handling=Handling +order.total.discount=Rebate + +label.order.recalculate=Recalculate + +label.order.transactions=Transactions list + +label.order.promocode.title=Promotion code +label.order.promocode.text=Enter your promotion code if you have one. + +#payment +label.payment.title=Payment methods +label.payment.module.title=Payment method + +label.payment.paypal.usepaypal=Use PayPal +label.payment.moneyorder.usemoneyorder=Use money order +label.payment.creditcard.usecredicard=Use your credit card +label.payment.creditcard.cardowner=Card Holder's Name +label.payment.creditcard.cardnumber=Card number +label.payment.creditcard.cardexpiry=Card expiry date +label.payment.creditcard.cardexpiry.month=Card expiry month +label.payment.creditcard.cardexpiry.year=Card expiry year +label.payment.creditcard.cardcvv=Card validation number +label.payment.creditcard.whatiscvv=What is a credit card validation number? + + +#tax +label.tax.taxclass.title=Tax classes +label.tax.taxclass=Tax class +label.tax.taxclass.name=Tax class name +label.tax.taxconfiguration=Tax basis calculation +label.tax.storeaddress=Store address +label.tax.piggyback=Piggy back +label.tax.compound=Compound + +#configuration +label.configuration.options=Configuration options +label.configuration.configurations=Configurations +label.configuration.google_analytics_url=Google Analytics URL (UC-XXXXXX) +label.configuration.google_api_key=Google API key (For maps) +label.configuration.facebook_page_url=FaceBook Page +label.configuration.twitter_handle=Twitter handle +label.configuration.pinterest=Pinterest +label.configuration.instagram=Instagram +label.social.connect=Connect with us +label.social.facebook=FaceBook +label.social.twitter=Twitter +label.configuration.useglobalsearch_suggestions=Use global pre-defined search suggestions +label.configuration.globalsearch_suggestions_path=Global pre-defined search suggestions file path + +#cart +label.emptycart=No items in your shopping cart +label.cart=Shopping cart +label.mycart=My cart +label.cart.revieworder=Review your order +label.cart.placeorder=Place your order + +label.shipping.nopostalcode=A shipping quote will be available after filling the postal code + +#checkout +label.checkout=Checkout +label.proceed.checkout=Proceed to checkout +label.subtotal=Sub-total +label.checkout.confirmation=Order completed + +#register +label.register.notyetregistered=Not yet registered? +label.register.whyregister=Why register? +label.register.registerreasons=Simplify a checkout process by having your information filed in, re-order an item from one click and get access to premium information. +label.register.confirmation=Registration has been completed with success! An email was sent to {0} with all authentication details. Got to {1} and use your authentication information to login. + +label.notification.message.passwordchanged=We would like to inform you that your password was recently changed on {0} +label.notification.title.passwordchanged=Password changed notification + + +#Email configuration +label.emailconfig.options=Email Configuration Options +label.emailconfig.protocol=Protocol +label.emailconfig.host=Host +label.emailconfig.port=Port +label.emailconfig.username=Username +label.emailconfig.password=Password +label.emailconfig.smtpauth=Requires authentication +label.emailconfig.starttls=STARTTLS +label.emailconfig.requiresauthentication=Email server requires authentication (should be true) +label.emailconfig.requiresstarttls=Some email servers such as Google mail requires starttls encryption + +label.adminurl=Administration url + +email.link=Link +email.link.reset.password.title=Reset password link +email.reset.password.text=Somebody requested your account password to be reset at {0}. If you did'nt asked this, you just can ignore the email. +email.username.label=Username : {0} +email.password.label=Password : {0} +email.administration.url=Administration url : {0} + +email.newuser.title=New user created +email.newstore.title=New store created +email.newstore.text=A new store has been created +email.newuser.text=A new user has been created +email.newstore.name=Store name : {0} +email.newstore.info=User informations will be sent on a separate email. + +email.order.title={0} - Order confirmation: {1} +email.order.confirmation=Order confirmation: {0} +email.order.comments=Notes: {0} +email.order.ordered=Ordered on : {0} +email.order.updated=Updated on : {0} +email.order.status.title=Order {0} updated +email.order.status=Last order status: {0} +email.order.thanks=Thanks for your purchase! +email.order.download.title=Download your files - Order confirmation: {0} +email.order.download.text=Your download files will be available for {0} days. You should have received an email with your login information to the system. Once logged in the system, navigate to the order details {1} and click on 'Download files'. You can get access to the customer section by clicking on the following link {2}. If you are having any difficulty with acceding to the customer section please send an email to {3}. + +email.contact=A new contact email - {0} +email.contact.title=Email contact form +label.checkout.logon=Logon or signup to simplify the online purchase process! + +label.checkout.text=Thank you for ordering from {0}. +label.checkout.orderid=Your order id is {0}. +label.checkout.email=An email with your order details has been sent to {0}. +label.checkout.additionaltext=If you have any comments or suggestions for us, please send us an email with your order id. We value your feedback. +label.checkout.downloads.completed=Here are your download files. +label.checkout.downloads.processing=An email with your file(s) download instructions will be sent once the payment for this order will be completed. + +label.entitylist.paging=Showing {0} - {1} of {2} result(s) + +label.checkout.moneyorder=Please make your check or money order payable to: + +email.user.resetpassword.text=A request has been made to reset you password. You will find herein your new password. +email.customer.resetpassword.text=A request has been made to reset you password. You will find herein your new password. +email.disclaimer=This email address was given to us by you or by one of our customers. If you feel that you have received this email in error, please send an email to {0} for de-activation +email.contactowner=If you have any questions on this request, please send an email to {0} in order to receive more details. +email.spam.disclaimer=This email is sent in accordance with the US CAN-SPAM Law in effect 2004-01-01. Removal requests can be sent to this address and will be honored and respected. +email.copyright=Copyright @ {0} {1}, All Rights Reserved +email.message.from=Message from {0} +email.greeting=Hi {0}, +email.customer.greeting=Thanks for joining {0}, you will be able to get access to the customer section by clicking on the following link {1}. Log on to the system and navigate to your order details. Informations to log in are included in this email. If you are having any difficulty with acceding to the customer section please send an email to {2}. +email.order.statustext=An update on the status has been made on order {0} ordered on {1} +email.order.status.changed=Order status changed: {0} -> {1} + + +# General Form +button.label.close=Close +button.label.esc=Esc key +button.label.submit=Save +button.label.submit2=Submit +button.label.submitorder=Submit order +button.label.ok=Ok +button.label.cancel=Cancel +button.label.edit=Edit +button.label.crop=Crop +button.label.reset=Reset +button.label.clear=Clear +button.label.clear.all=Clear all +button.label.add=Add +button.label.update=Update +button.label.removeservice=Remove Service +button.label.getcode=Get code +button.label.logout=Logout +button.label.logon=Logon +button.label.login=Login +button.label.signin=Sign in +button.label.register=Register +button.label.select=Select +button.label.subscribe=Subscribe +button.label.printreport=Print report +button.label.upload.images=Upload Images +button.label.upload.files=Upload Files +button.label.resetpassword=Reset Password +button.label.forgotpassword=Forgot Password? +button.label.view=Details +button.label.addToCart=Add to cart +button.label.continue=Continue shopping + +#menus +menu.home=Home +menu.catalogue=Catalogue +menu.store=Store +menu.storeDetails=Store +menu.storeLanding=Store home page +menu.storeBranding=Store branding +menu.catalogue-products=Products +menu.catalogue-products-create=Create product +menu.catalogue-categories=Categories +menu.catalogue-categories-create=Create category +menu.catalogue-categories-list=List of categories +menu.catalogue-categories-hierarchy=Category hierarchy +menu.catalogue-products-categories=Products to categories +menu.catalogue-options=Options +menu.catalogue-products-images=Product images +menu.catalogue-products-images-url=Product images external url +menu.catalogue-options-create=Create option +menu.catalogue-options-list=Options list +menu.catalogue-optionsvalues-create=Create option value +menu.catalogue-optionsvalues-list=Options values list +menu.catalogue-products-group=Products group +menu.catalogue-featured=Featured items +menu.catalogue-products-custom-group=Products custom groups +menu.customer=Customers +menu.profile=Profile +menu.users=Users +menu.user=User +menu.myprofile=My profile +menu.change-password=Change password +menu.create-user=Create a user +menu.create-store=Create a store +menu.store-list=Stores +menu.security=Security +menu.security-permissions=Permissions +menu.security-groups=Groups +menu.security-create-group=Create group +menu.order=Orders +menu.order-list=List of orders +menu.shipping=Shipping +menu.shipping-configs=Shipping configurations +menu.shipping-methods=Shipping methods +menu.shipping-options=Shipping options +menu.shipping-packages=Packaging +menu.shipping-origin=Shipping origin +menu.configuration=Configurations +menu.cache=Cache management +menu.customer-list=List of customers +menu.customer-create=Create customer +menu.customer-options=Customer options +menu.customer-options-list=List of customer options +menu.customer-options-create=Create customer option +menu.customer-options-values-list=List of customer option values +menu.customer-options-values-create=Create customer option value +menu.customer-options-set=Manage customer options set +menu.content=Manage content +menu.content-pages=Manage pages +menu.content-boxes=Manage boxes +menu.content-images=Manage images +menu.content-images-create=Create images +menu.content-pages-create=Create page +menu.content-boxes-create=Create box +menu.content-files=Manage files +menu.payment=Payment +menu.tax=Manage taxes +menu.taxconfiguration=Tax configuration +menu.taxclass=Tax classes +menu.taxrates=Tax rates +menu.taxrates.rate=Tax rate +menu.taxrates.code=Tax rate code +menu.taxrates.name=Tax rate name +menu.product.category=Associate to categories +menu.accounts-conf=Accounts configuration +menu.email-conf=Email settings +menu.system-configurations=System configurations +menu.manufacturer-list=List of manufacturers +menu.manufacturer-create=Create manufacturer +menu.addaddress=Add a new address diff --git a/sm-shop/src/main/resources/bundles/shopizer_fr.properties b/sm-shop/src/main/resources/bundles/shopizer_fr.properties new file mode 100755 index 0000000000..1df60a2ca4 --- /dev/null +++ b/sm-shop/src/main/resources/bundles/shopizer_fr.properties @@ -0,0 +1,789 @@ +label.quantity=Quantité + +label.defaultlanguage=Langue par défaut +label.defaultSelection=Sélection par défaut +lang.en=Anglais +lang.fr=Français +lang.ru=Russe +lang.es=Espagnol +lang.ar=Arabe +lang.pt-BR=Portugais +label.shop=Magasiner +label.entity.id=Identifiant +label.entity.name=Nom +label.entity.code=Code +label.entity.visible=Visible +label.entity.featured=Vedette +label.entity.active=Actif +label.entity.public=Public +label.entity.details=Détails +label.entity.type=Type +label.entity.remove.confirm=Désirez-vous vraiement détruire cette entitée ? +label.entity.setAsDefault.confirm=Désirez-vous assigner cette entité par défaut ? +label.entity.order=Ordre +label.entity.status=Status +label.generic.all=Tout +label.generic.email=Adresse courriel +label.generic.address=Adresse +label.generic.city=Ville +label.generic.country=Pays +label.generic.price=Prix +label.generic.phone=Téléphone +label.generic.back=Retour +label.generic.setAsDefault=Configurer par défaut +label.generic.country.code=Code du pays +label.generic.stateprovince=État / province +label.generic.postalcode=Code postal +label.generic.item=article +label.generic.item.title=Article +label.generic.items=articles +label.generic.displayonly=Affichage seulement +label.generic.url=URL +label.generic.sortby=Ordonner par +label.generic.default=Défaut +label.generic.name=Nom +label.generic.next=Suivant +label.generic.genre=Genre +label.generic.male=Homme +label.generic.female=Femme +label.generic.register=Enregistrer +label.generic.youropinion=Votre opinion +label.generic.date=Date +label.generic.comments=Commentaires +label.generic.subject=Sujet +label.generic.minimum=Minimum +label.generic.maximum=Maximum +label.generic.pictures=Photos +label.generic.videos=Vidéos +label.generic.imageType=Type de média +label.generic.today=Aujourd'hui + +label.generic.welcome=Bonjour +label.generic.weightunit.LB = Livres +label.generic.weightunit.KG = Kilogrammes +label.generic.language=Langue +label.generic.search=Recherche + +label.generic.sizeunit.CM = Centimètres +label.generic.sizeunit.IN = Pouces +label.generic.remove=Retirer +label.generic.yes=Oui +label.generic.no=Non +label.generic.alphanumeric=Alpha numérique +label.generic.add=Ajouter +label.generic.username=Nom d'usager +label.generic.edit=Changer +label.generic.print=Imprimer + +label.generic.environment=Environnement +label.generic.providedby=Propulsé par + +label.generic.title=Titre +label.generic.keywords=Mots clés +label.generic.amount=Montant +label.generic.changepassword=Change password + +label.generic.confirm=Veuillez confirmer! +label.generic.firstname=Prénom +label.generic.lastname=Nom +label.generic.streetaddress=Adresse civique +label.generic.postalcode=Code postal +label.generic.city=Ville +label.generic.country=Pays +label.generic.hi=Bonjour +label.generic.send=Envoyer +label.generic.rebate=Rabais + +label.soldout=Non disponible + +#merchant store +label.store.information.title=Informations +label.store.title=Boutique +label.store.information=Informations sur la boutique +label.storeadministration=Administration de la boutique +label.storeadministrator = Administrateur de la boutique +label.storename = Nom de la boutique +label.storecode=Code unique de la boutique +label.currency = Devise +label.bgcolorcode = Couleur de fond +label.storelogo = Logo de la boutique +label.storebanner = Banniére de la boutique +label.storephone = Téléphone de la boutique +label.accepteddomains = Domaines acceptÈs +label.storeaddress = Adresse de la boutique +label.storecity = Ville de la boutique +label.storepostalcode = Code postal de la boutique +label.storecountry = Pays de la boutique +label.storezone = État / Région / Province de la boutique +label.supportedlanguages = Langues prises en charge +label.storeemailaddress = Adresse e-mail de la boutique +label.storesetup = Configuration de la boutique +label.store.template=Thème +label.store.baseurl=Url de base de la boutique (domaine) +label.store.inbusinesssince=Boutique web en opération depuis +label.changepasswordrequest = Demande de changement de mot de passe +label.store.weightunit=Unités de poids +label.store.sizeunits=Unités de grandeur +label.store.list=Boutiques +label.store.useCache=Utiliser la cache +label.store.currency.format=Format de la monaie national +label.store.currency.format.help=Format de la monaie national ex $1,345.79 ou Format de la monaie international ex USD1,345.79 + +label.store.displaycontactussection=Afficher la page contactez-nous +label.store.displaystoreaddress=Afficher l'adresse de la boutique +label.store.displaysearchbox=Afficher la boîte de recheche +label.store.displaypagesmenu=Afficher le menu des pages +label.store.testmode=Mode tests (cache les catégories et le détail des produits) +label.store.debugmode=Mode 'debug' (ajoute des traces additionnelles) +label.store.allowPurchaseItems=Permettre l'achat d'items +label.store.displayaddtocartfeatured=Permettre l'ajout au panier à partir des articles recommandés +label.store.tofindus=Notre adresse + +label.storefront.storetext = Contenu de la page principale +label.storefront.metatags.keywords = (Meta tags) Mots-clés +label.storefront.metatags.description = (Meta tags) Description +label.storefront.landingpage.title = Titre de la page principale + +#user +label.profile.title=Profile de l'utilisateur +label.my.profile=Mon profile +label.profile.lastaccess=Dernier accès +label.register.personal.information=Informations personnelles +label.register.signin.information=Informations d'authentification +label.register.createaccount=Crééer un compte + +#search +label.search.searchQuery=mots recherchés +label.search.items.found=article(s) trouvé(s) + + +label.generic.password=Mot de passe +label.generic.repeatpassword=Répéter le mot de passe +label.generic.newpassword=Nouveau mot de passe +label.generic.newpassword.repeat=Répéter le nouveau mot de passe + +label.store.question=Vous avez des questions ? + +security.question.1=Quelle était la couleur de votre première voiture ? +security.question.2=Dans quelle ville êtes-vous né ? +security.question.3=Quel était le nom de votre premier animal de compagnie ? +security.question.4=Quel est votre genre de musique préféré ? +security.question.5=Qui était le héro de votre enfance ? +security.question.6=Dans quelle ville était votre premier emploi ? +security.question.7=À quel endroit étiez-vous lors de votre premier baiser ? +security.question.8=Dans quelle ville avez vous rencontré votre conjoint/conjointe ? +security.question.9=Quel surnom aviez-vous dans votre enfance ? + +security.questions.differentmessages=Choisir 3 questions différentes + +security.question1=Question 1 +security.question2=Question 2 +security.question3=Question 3 +security.answer.question1.message=Veuillez répondre à la question de sécurité 1 +security.answer.question2.message=Veuillez répondre à la question de sécurité 2 +security.answer.question3.message=Veuillez répondre à la question de sécurité 3 + + +security.group.description.SUPERADMIN=Un seul usager est créé super admin. L'usager 'admin' créé par défaut par le systeème est l'usager superadmin. Cet usager peut tout administrer et il est le seul usager pouvant créeer et supprimer une boutique. +security.group.description.ADMIN=Un usager admin possède le plus de privilèges dans lèadministration de la boutique.Un usager admin peut tout administrer dans une boutique et peut également créer d'autres usagers ayant des accès plus restreints. +security.group.description.ADMIN_CATALOGUE=Un usager appartenant à ce groupe peut gérer les catégories et les produits. Il peut également configurer les produits vedettes. +security.group.description.ADMIN_STORE=Un usager appartenant à ce groupe peut administrer toutes configurations reliées à la boutique. L'usager peut également administrer les configurations de paiement et de livraison. +security.group.description.ADMIN_ORDER=A user part of that group can manage orders, search for orders, modify customer information, apply refund to an order. +security.group.description.ADMIN_CONTENT=A user assigned to that group will be able to manage the site dynamic and static content, add images, aand files to the system. + +label.security.loggedinas=Vous êtes authentifié avec +label.security.nologinacces.store=Impossible de s'authentifier dans cette section. + +#customer +label.customer.registered=Client enregistré +label.customer.new=Nouveau client +label.customer.registered.signinemail=Si vous avez déjà un compte veuillez vous enregistrer avec votre addresse de courriel +label.customer.signin.social=Encore plus simple, connectez-vous avec votre compte {0} ! +label.customer.signin.social.system=Connectez-vous avec {0} +label.customer.faster=Il y a plusieurs bénéfices à créer un compte dont simplifier le processus d'achat, obtnir des informations sur vos commandes et bien plus. +label.customer.myaccount=Mon compte +label.customer.contactus=Contactez-nous +label.customer.list=Liste de clients +label.customer.customerlist.title = Liste des clients +label.customer.customerdetails.title = Détails du client +label.customer.name = Nom du client +label.customer.lastname = Nom de famille du client +label.customer.firstname = Prénom du client +label.customer.id = Identifiant du client +label.customer.companyname = Nom de l'entreprise +label.customer.email = Adresse e-mail du client +label.customer.streetaddress = Adresse +label.customer.suburb = Banlieue +label.customer.postalcode = Code postal +label.customer.telephone = Téléphone +label.customer.city = Ville +label.customer.zone = État / Province +label.customer.country = Pays +label.customer.editcustomer=Éditer un client +label.customer.createcustomer=Créer un client +label.customer.order.date= Date de la commande +label.customer.order.agreement=Je suis d'accord avec les termes et conditions +label.customer.order.agreement.title=Termes et conditions +label.customer.options.edit=Éditer l'option + +label.customer.billinginformation =Informations sur la facturation +label.customer.shippinginformation =Informations sur la facturation et la livraison +label.customer.billingshipping=Informations de facturation et de livraison +label.customer.shippingaddress=Adresse de livraison +label.customer.billingaddress=Adresse de facturation + + +label.customer.edit.billingaddress=Modifier l'adresse de facturation +label.customer.edit.shippinginformation=Modifier l'adresse de livraison + + +label.customer.billing.company=Nom de l'entreprise +label.customer.billing.streetaddress = Adresse de facturation +label.customer.billing.suburb = Banlieue de facturation +label.customer.billing.postalcode = Code postal de facturation +label.customer.billing.city = Ville de facturation +label.customer.billing.zone =État / province de facturation +label.customer.billing.country = Pays de facturation +label.customer.billing.firstname = Prénom sur la facturation +label.customer.billing.lastname = Nom de famille sur la facturation +label.customer.billing.name=Nom sur la facturation + +label.customer.shipping.company=Company de livraison +label.customer.shipping.streetaddress=Adresse de livraison +label.customer.shipping.suburb=Banlieue de livraison +label.customer.shipping.postalcode=Code postal de livraison +label.customer.shipping.city=Ville de livraison +label.customer.shipping.zone=État / province de livraison +label.customer.shipping.country=Pays de livraison +label.customer.shipping.firstname=Prénom à la livraison +label.customer.shipping.lastname=Nom de famille à la livraison +label.customer.shipping.name=Nom à la livraison +label.customer.shipping.shipaddress=Livrer à cette adresse +label.customer.shipping.shipdifferentaddress=Livrer à une adresse différente ? + +label.customer.confirmshippingaddress=Confirmation de l'adresse de livraison + + + +label.customer.optionv.edit=Éditer une option +label.customer.option.name=Nom de l'option +label.customer.option.code=Code de l'option +label.customer.option.type=Type d'affichage + +label.customer.optionvalue.edit=Éditer la valeur d'option +label.customer.optionvalue.name=Nom de la valeur d'option +label.customer.optionvalue.code=Code de la valeur d'option + +label.customer.displaycustomersection=Afficher la section client +label.customer.accessportal=Vous pouvez accéder à la section des utilisateurs en suivant ce lien +label.customer.accessnow=Accéder maintenant ! + +label.customer.resetpasswor.confirm=Êtes-vous certain de vouloir ré-initialiser le mot de passe ? +label.customer.moredetails=Plus de détails ! +label.order.editcustomer=Éditer le client +label.order.displayagreement=Afficher les termes et conditions dans la page d'achat +label.order.notes=Notes +label.order.notes.eg=Notes pour la commande ou pour la livraison + +label.customer.currentpassword=Mot de passe actuel +label.customer.newpassword=Nouveau mot de passe +label.customer.repeatpassword=Répéter le mot de passw + +label.customer.createaccount=Créer un compte ? +label.customer.accountpassword=Mot de passe du compte +label.customer.createaccount.text=Créez un compte en fournissant les informations requises ci-bas. Si vous possédez déjà un compte utilisez le lien au haut de la page permettant de vous authentifier. + +#permission +label.permissions.title=Permissions +label.permission.editpermission=Éditer les permissions +label.permission.createpermission=Créer une permission +label.permission.name=Nom de la permission + +#groups +label.groups.title=Groupes +label.group.editgroup=éditer un groupe +label.group.creategroup=Créer un groupe +label.group.root=Racine +label.group.groupId=Identifiant du groupe + +#category +label.category.title=Titre de la catégorie +label.category.highlight=Description éclair +label.categories.title=Catégories +label.categories.hierarchy.title=Hierarchie des catégories +label.category.root=Racine +label.productedit.categoryname = Nom de la catégorie +label.productedit.choosecategory = Choisissez une catégorie +label.category.categogydetails = Détails de la catégorie +label.category.editcategory = Modifier la catégorie +label.category.movecategory = Déplacer la catégorie +label.category.moveundercategory = Déplacer sous la catégorie +label.category.createcategory = Créer une catégorie +label.category.code=Code de la catégorie +label.category.categoryvisible = Catégorie visible +label.category.categorydescription = Description de la catégorie +label.category.parentcategory = Catégorie parent +label.category.hierarchy.text=Glisser les catégories pour ré-organiser la hierarchie +label.category.maincategories=Main categories + +#manufacturer +label.manufacturer.brand=Marques +label.manufacturer.edit=éditer le manufacturier +label.manufacturer.create=Créer un manufacturier +label.manufactureredit.manufacturername=Nom du manufacturier +label.manufactureredit.manufacturertitle=Titre du manufacturier +label.manufactureredit.manufacturerurl=URL +label.manufactureredit.manufacturerurlclicked=URL clique +label.manufactureredit.manufacturerdescription=Description du manufacturier +label.manufacturer.image=Image +label.manufactureredit.manufacturerorder=Sequence + +#product +label.sefurl=Lien convivial +label.metatags.description = (Meta tags) Description +label.metatags.keywords = (Meta tags) Mots-clés +label.product.sku=Sku +label.product.refsku=Identifiant de l'item dans le système de référence +label.product.available=Disponible +label.product.create=Créer a produit +label.product.edit=éditer le produit +label.productedit.productname=Nom du produit +label.productedit.producthl=Description éclair +label.productedit.productdesc=Description du produit +label.product.title=Titre du produit +label.product.price=Prix du produit +label.product.price.code=Code de prix du produit +label.product.preorder=Pré-commande +label.product.price.name=Nom du prix +label.product.price.priceAppender=Suffix de prix +label.product.price.default=Prix par défaut +label.product.price.special=Prix rabais +label.product.price.special.startdate=Date de début du rabais +label.product.price.special.enddate=Date de fin du rabais +label.taxclass = Classe de taxe +label.product.ordermax=Quantitée maximum permise +label.product.ordermin=Quantity minimum permise +label.product.weight =Poids +label.product.height =Hauteur +label.product.length =Profondeur +label.product.width =Largeur +label.product.image =Image +label.product.uploadfile = Importer un fichier +label.product.details=Détails du produit +label.product.prices=Prix du produit +label.product.attributes=Options du produit / Attributs +label.product.attribute=Option du produit / Attribut +label.product.attribute.default=Option par défault +label.product.attribute.required=Option requise +label.product.attribute.display=Attribut utilisé pour lecture seulement +label.product.attribute.otherweight=Poids additionnel +label.product.attribute.option.name=Nom de l'option / attribut +label.product.attribute.value=Valeur de l'attribut +label.product.price.create=Créer un prix +label.product.attribute.create=Créer une option / attribut +label.product.attribute.specifications=Spécifications +label.product.category.association=Associer le produit aux catégories +label.product.customer.reviews=Revues du client +label.product.reviews=Revue(s) du produit +label.product.reviews.rating=Évaluation +label.product.reviews.write=Évaluer ce produit +label.product.reviews.logon.write=Vous devez vous authentifier afin d'évaluer ce produit +label.product.reviews.evaluated=Vous avez évalué ce produit +label.product.featured.meassage=Pour ajouter un produit à la liste des produits vedettes faites glisser le produit du contenant des produits vers la boîte des produits vedetted. +label.product.group.meassage=Pour ajouter un produit à la liste du groupe de produits faites glisser le produit du contenant des produits vers la boîte du groupe de produit courant. +label.product.related.title=Produits connexes +label.product.related.meassage=Pour ajouter un produit à la liste des produits connexes faites glisser le produit du contenant des produits vers la boîte des produits connexes. +label.product.createsimilar=Créer un produit similaire +label.product.configure=Définition du produit +label.product.specification=Spécification +label.product.digitalproduct=Produit virtuel +label.product.specials=Spéciaux +label.product.brand=Marque +label.product.code=Code de produit +label.product.nomoreitems=Fin des articles à afficher +label.product.moreitems=Afficher plus d'articles +label.product.searchkeywords=Mots clés de recherche +label.product.shipeable=Le produit doit être livré +label.product.outofstock=Non disponible +label.product.defaultImage.message=En choisissant l'option défaut, cette image sera affichée comme image principale dans le page de produit + +#options +label.product.productoptions.edit.title=Modifier une option de produit +label.product.productoptions.create.title=Créer une option de produit +label.product.productoptions.title=Option du produit +label.product.productoptions.name =Nom de l'option +label.product.productoptions.price=Prix de l'option +label.product.productoptions.comments=Commentaires +label.product.productoptions.type=Type d'option + +label.product.productoption.type.text=Texte +label.product.productoption.type.radio=Radio +label.product.productoption.type.select=Select +label.product.productoption.type.checkbox=Checkbox + +label.product.customGroup.title=Groupe de produits +label.product.customgroup.add=Ajouter un groupe de produits +label.product.customgroup.code=Code du groupe de produit (doit être unique) + +label.product.rate=Évaluer ce produit +label.product.clickrate=Évaluation du produit (cliquez sur les images pour activer l'évaluation) + + +label.product.option.displayonly=Option pour affichage seulement +label.product.option.code=Code de l'option +label.product.option.codehelp=Code de l'option requis pour effectuer des recherches de produits par attribut + + +#options values +label.product.productoptionsvalues.title=Valeurs des options de produit +label.product.productoptionsvalues.list=Liste des valeurs des options de produit +label.product.productoptiosvalue.title=Valeur d'option +label.product.productoptionvalue.edit.title=Modifier une valeur d'option +label.product.productoptionvalue.create.title=Créer une valeur d'option +label.product.productoptionvalue=Image de valeur d'option + +#content Images - Files +label.page=Page +label.contentImages.store=Boutique marchand +label.content.images=Librairie d'images +label.content.files=Librairie de fichiers +label.content.pages=Pages de contenu +label.content.pages.manage.content=Gestion du contenu des pages +label.content.manage.content=Gestion du contenu +label.content.pages.page.name=Nom de la page +label.content.pages.page.content=Contenu de la page +label.content.boxes=Boîtes de contenu +label.content.boxes.position=Position de la boîte +label.content.boxes.name=Nom de la boîte +label.content.sections=Sections de contenu +label.content.friendlyurl=URL simplifié +label.content.metatag.description=Méta donnée de description +label.content.page.displaymainmenu=Afficher un line vers cette page dans le menu principal + + +#shipping +label.shipping.title=Configuration expédition +label.shipping.national=National +label.shipping.international=International +label.shipping.mode=Statut d'expédition +label.shipping.methods=Méthodes d'expédition +label.shipping.countries=Pays d'expédition +label.shipping.options=Options d'expédition +label.shipping.taxonshipping=Appliquer la taxe sur l'expédition +label.shipping.freeshipping=Livraison gratuite +label.shipping.freeshippingamount=Livraison gratuite sur une commande dont le montant est supérieur à +label.shipping.handlingfees=Frais de manutention +label.shipping.packaging.title=Packaging information +label.shipping.packaging.individual=Les items seront expédiés séparément +label.shipping.packaging.boxes=Les items seront combinés et expédiés dans une boîte +label.shipping.packaging.box.height=Hauteur de la boîte +label.shipping.packaging.box.length=Longueur de la boîte +label.shipping.packaging.box.width=Largeur de la boîte +label.shipping.packaging.box.weight=Poids de la boîte +label.shipping.packaging.box.maxweight=Poids maximum supporté par la boîte +label.shipping.packaging.box.maxitems=Nombre maximum d'items dans la boîte +label.shipping.addregion=Ajouter une région +label.shipping.region=Région +label.shipping.allquotes=Afficher toutes les catations obtenues +label.shipping.leastexpensivequotes=Afficher la catations obtenue la moins dispendieuse +label.shipping.moreexpensivequotes=Afficher la catations obtenue la plus dispendieuse +label.message.region.available=Région disponible +label.message.region.exist=Région existe déjà +label.shipping.maximumWeight=Poids maximum +label.shipping.shippingaddress=Adresse de livraison +label.shipping.billingaddress=Adresse de facturation +label.message.maximumWeight.exist=Poids maximum existe déjà +label.shipping.fees=Frais de livraison +label.shipping.freeshipping=Livraison gratuite ! +label.shipping.freeshipping.over=Livraison gratuite pour les commandes dont le montant est supérieur à +label.shipping.freeshippingandhandling=Livraison et manutention gratuits +label.shipping.origin.title=Adresse source de la livraison +label.shipping.origin.description=L'adresse source de la livraison sert à calculer la distance entre l'origine et la destination d'une livraison. Si elle n'est pas populée, le système utilisera l'adresse de la boutique comme adresse d'origine. + + +#order +label.order.title=Commandes +label.order.total=Total +label.order.totals=Total +label.order.date=Date de la commande +label.order.module=Module du paiement +label.order.shippingmethod=Mode d'expédition +label.order.paymentmode=Mode de paiement +label.order.refund=Appliquer un remboursement +label.order.capture=Compléter la transaction +label.order.item=Article +label.order.price=Prix +label.order.sendinvoice=Envoyer la facture par courriel +label.order.printinvoice=Imprimer la facture +label.order.packing=Imprimer l'étiquette d'expédition +label.order.updatestatus=Envoyer un statut de la commande +label.order.downloademail=Envoyer les instructions de téléchargement +label.order.history=Historique +label.order.recent=Dernières commandes +label.order.pastorders=Historique des commandes +label.order.summary=Sommaire de la commande +label.order.details=Détails de la commande +label.order.PROCESSING=En traîtement +label.order.ORDERED=Commandée +label.order.PAID=Payée +label.order.SHIPPED=Livrée +label.order.PREPARED=Préparés +label.order.REFUNDED=Remboursée +label.order.DELIVERED=Livrée +label.order.CANCELED=Annulée +refund=Remboursement + +order.total.subtotal=Sous-total +order.total.total=Total +order.total.shipping=Livraison +order.total.handling=Manutention +order.total.discount=Rabais + +label.order.recalculate=Recalculer +label.order.transactions=Liste des transactions + +label.order.promocode.title=Code promotionnel +label.order.promocode.text=Saisissez votre code de promotion si vous en prooédez un. + +#payment +label.payment.title=Méthodes de paiement +label.payment.module.title=Méthode de paiement + +label.payment.paypal.usepaypal=Utiliser PayPal +label.payment.moneuorder.usemoneyorder=Utiliser une traîte bancaire +label.payment.creditcard.usecredicard=Utitliser votre carte de crédit +label.payment.creditcard.cardowner=Nom inscrit sur la carte +label.payment.creditcard.cardnumber=Numéro de la carte +label.payment.creditcard.cardexpiry=Date d'expiration de la carte de crédit +label.payment.creditcard.cardexpiry.month=Mois d'expiration +label.payment.creditcard.cardexpiry.year=Année d'expiration +label.payment.creditcard.cardcvv=Numéro de validation de la carte de crédit +label.payment.creditcard.whatiscvv=Qu'est-ce que le numéro de validation de la carte de crédit ? + +#tax +label.tax.taxclass.title=Classes de taxes +label.tax.taxclass=Classe de taxe +label.tax.taxclass.name=Nom de la classe de taxe +label.tax.taxconfiguration=Bases du calcul des taxes +label.tax.storeaddress=Adresse de la boutique +label.tax.piggyback=Cumulée à une autre taxe +label.tax.compound=Composée à une autre taxe + +#configuration +label.configuration.options=Options de configuration +label.configuration.configurations=Configurations +label.configuration.google_analytics_url=URL Google Analytics (UC-XXXXXX) +label.configuration.google_api_key=Clée Google pour API (pour les cartes) +label.configuration.facebook_page_url=URL de la page FaceBook +label.configuration.twitter_handle=Compte Twitter +label.configuration.pinterest=Pinterest +label.configuration.instagram=Instagram +label.social.connect=Restons en contact +label.social.facebook=FaceBook +label.social.twitter=Twitter +label.configuration.useglobalsearch_suggestions=Utiliser un fichier global de recherches pré-défini +label.configuration.globalsearch_suggestions_path=Chemin d'accès du fichier global de recherches pré-défini + +#cart +label.emptycart=Aucun item dans le panier d'achat +label.cart=Panier d'achat +label.mycart=Mes achats +label.cart.revieworder=Revoir votre commande +label.cart.placeorder=Passez votre commande + +#checkout +label.checkout=Paiement +label.proceed.checkout=Effectuer le paiement +label.subtotal=Sous-total +label.checkout.confirmation=La commande a été complétée + +label.shipping.nopostalcode=Les frais de livraison seront ajustés après avoir inscrit votre code postal. + +#register +label.register.notyetregistered=Pas encore enregistré ? +label.register.whyregister=Pourquoi s'enregistrer ? +label.register.registerreasons=Simplifiez le processus d'achat en créant au préalables les informations de facturation et d'envoi des commandes. Vous aurez accès à une section vous permettant de faire le suivi de vos commandes et d'imprimer vos factures d'achats. +label.register.confirmation=L'enregistrement a été complété avec succès ! Un couriel a été envoyé à {0} comprenant les informations permettant de se connecter. Allez à {1} afin de vous connecter au système. + +label.notification.message.passwordchanged=Nous désirons vous informer qu'une demande de changement de votre mot de passe a été faite le {0} +label.notification.title.passwordchanged=Notification d'un changement de mot de passe + + +#Email configuration +label.emailconfig.options=Configurations du serveur email +label.emailconfig.protocol=Protocole +label.emailconfig.host=Hôte +label.emailconfig.port=Port +label.emailconfig.username=Nom d'usager +label.emailconfig.password=Mot de passe +label.emailconfig.smtpauth=Authentication requise +label.emailconfig.starttls=STARTTLS +label.emailconfig.requiresauthentication=Le serveur email requiert une authentification (devrait être vrai) +label.emailconfig.requiresstarttls=Certains serveurs email tels que Google mail requierent l'utilisation de l'encryption STARTTLS + +label.adminurl=Adresse du site d'administration +email.newuesr.title=Nouvel usager créé + +email.link=Lien +email.link.reset.password.title=Réinitialiser le mot de passe +email.reset.password.text=Quelqu'un a demandé la réinitialisation du mot de passe de votre compte {0}. Si vous n'avez pas fait cette, vous pouvez simplement ignorer ce message. +email.username.label=Code d'usager : {0} +email.password.label=Mot de passe : {0} +email.administration.url=Lien administration : {0} + +email.newstore.title=Création d'un nouveau marchand +email.newstore.text=Un nouveau marchand a été créé +email.newuser.text=Un nouvel usager a été créé +email.newstore.name=Nom du marchand : {0} +email.newstore.info=Les informations de l'usager seront envoyées dans un couriel différent. + +email.order.title={0} - Confirmation : {1} +email.order.confirmation=Numéro de confirmation de la commande : {0} +email.order.ordered=Commandé le : {0} +email.order.comments=Notes: {0} +email.order.updated=Mis à jour le : {0} +email.order.status.title=Commande {0} mise à jour +email.order.status=Dernier statut de la commande : {0} +email.order.thanks=Merci pour cette commande ! +email.order.download.title=Téléchargez vos fichiers - Commande : {0} +email.order.download.text=Vos fichiers prêts à télécharger seront disponibles pendant {0} jours. Vous devriez avoir reçu un courriel avec les informations nécessaires à l'accès au système. Une fois authentifié dans le système, naviguez vers le détail de la commande {1} et cliquez sur 'Télécharger mes fichiers'. Vous avez accès au système en suivant ce lien {2}. Si vous avez des difficultées à accéder à la section client, envoyez un couriel à {3}. +email.order.status.changed=Order status changed: {0} -> {1} + +email.contact=Nouveau contact - {0} +email.contact.title=Formulaire de contact +label.checkout.logon=Vous pouvez vous authentifier ou vous abonner afin de simplifier le processus d'achats ! + + +label.checkout.text={0} vous remercie d'avoir acheté chez nous. +label.checkout.orderid=Votre numéro de commande est {0}. +label.checkout.email=Un courriel contenant le détail de la commande a été envoyé à {0}. +label.checkout.additionaltext=Si vous avez des commentaires ou suggestions à nous envoyez vous pouvez le faire par courriel en prenant le soin de mentionner le numéro de votre commande. +label.checkout.downloads.completed=Voici le(s) fichier(s) à télécharger. +label.checkout.downloads.processing=Un courriel contenant un lien vers le(s) fichier(s) à télécharger vous sera envoyé dès que le paiement pour cette commande sera complété. + +label.entitylist.paging=Affichage de {0} - {1} de {2} résultat(s) + +label.checkout.moneyorder=S'il vous plaît faire votre chèque ou mandat à l'ordre de : + +email.user.resetpassword.text=Une requête a été faite afin de ré-initialiser votre mot de passe. Vous trouverez ci-joint votre nouveau mot de passe. +email.customer.resetpassword.text=Une requête a été faite afin de ré-initialiser votre mot de passe. Vous trouverez ci-joint votre nouveau mot de passe. +email.disclaimer = Cette adresse de courriel nous a été donnée par vous ou par un de nos clients. Si vous pensez que vous avez reçu ce courriel par erreur, s''il vous plaît envoyez un courriel à {0} pour procéder à la désactivation +email.contactowner=Si vous avez des questions concernant cette requête, envoyez un message courriel à {0} afin de recevoir plus de détails. +email.spam.disclaimer = Ce courriel est envoyé en conformité avec la loi CAN-SPAM américaine en vigueur le 2004-01-01. Les demandes de suppression peuvent être envoyées à cette adresse et seront honorées et respectées. +email.copyright=Tous droits réservés {0} {1} +email.message.from = Message de {0} +email.greeting=Bonjour {0}, +email.customer.greeting=Merci de vous joindre à {0}, vous pourrez accéder à la section des clients en utilisant ce lien {1}. Authentifiez-vous au système et naviguez vers la section de détail des commandes. Les informations vous permettant de vous authentifier sont incluses dans ce couriel. Si vous avez des difficultées à accéder à la section client, envoyez un couriel à {2}. +email.order.statustext=Une mise à jour a été faite à la commande {0} commandée le {1} +email.order.status=Mis à jour le {0} - Dernier statut de la commande {1} + + +# Formulaire général +button.label.close = Fermer +button.label.esc = Touche Esc +button.label.submit=Sauvegarder +button.label.submit2=Soumettre +button.label.submitorder=Passer la commande +button.label.ok=Ok +button.label.edit=éditer +button.label.cancel = Annuler +button.label.crop = Redimensioner +button.label.reset = Ré-initialiser +button.label.clear = Effacer +button.label.clear.all=Effacer tout +button.label.add = Ajouter +button.label.update = Mise à jour +button.label.removeservice = Supprimer le Service +button.label.getcode = Obtenir le code +button.label.logout = Déconnection +button.label.logon = Authentifier +button.label.login = Connection +button.label.signin=Authentification +button.label.register=S'enregistrer +button.label.select = Sélectionner +button.label.subscribe = S'abonner +button.label.printreport=Imprimer un rapport +button.label.upload.images=Ajouter des fichiers +button.label.resetpassword=Ré-initialiser le mot de passe +button.label.forgotpassword=Mot de passe oublié ? +button.label.view=Détails +button.label.addToCart=Ajouter au panier +button.label.continue=Continuez votre magasinage + +menu.home=Page d'accueil +menu.catalogue=Catalogue +menu.store=Boutique +menu.storeDetails=Boutique +menu.storeLanding=Boutique - page principale +menu.storeBranding=Boutique - image de marque +menu.catalogue-products=Produits +menu.catalogue-products-create=Créer un produit +menu.catalogue-categories=Catégories +menu.catalogue-categories-create=Créer une catégorie +menu.catalogue-categories-list=Liste des catégories +menu.catalogue-categories-hierarchy=Structure des catégories +menu.catalogue-products-categories=Produits - Catégories +menu.catalogue-options=Options +menu.catalogue-products-images=Images du produit +menu.catalogue-products-images-url=Url de l'image du produit +menu.catalogue-options-create=Créer une option +menu.catalogue-options-list=Liste des options +menu.catalogue-optionsvalues-create=Créer une valeur d'option +menu.catalogue-optionsvalues-list=Liste des valeurs d'options +menu.catalogue-products-group=Groupes de produits +menu.catalogue-featured=Articles vedettes +menu.catalogue-products-custom-group=Autres groupes de produits +menu.customer=Clients +menu.profile=Profile +menu.users=Utilisateurs +menu.user=Utilisateur +menu.myprofile=Mon profile +menu.change-password=Changement de mot de passe +menu.create-user=Créer un utilisateur +menu.create-store=Créer une boutique +menu.store-list=Liste des boutiques +menu.security=Securité +menu.security-permissions=Permissions +menu.security-groups=Groupes +menu.security-create-group=Créer un groupe +menu.order=Commandes +menu.order-list=Liste des commandes +menu.shipping=Expédition +menu.shipping-configs=Configurations de l'expédition +menu.shipping-methods=Méthodes d'expédition +menu.shipping-options=Options d'expédition +menu.shipping-packages=Emballage +menu.shipping-origin=Adresse d'origine de la livraison +menu.cache=Gestion de la cache +menu.configuration=Configurations +menu.customer-list=Liste des clients +menu.customer-create=Créer un client +menu.customer-options=Options du client +menu.customer-options-list=Liste des options du client +menu.customer-options-create=Créer une option de client +menu.customer-options-values-list=Liste de valeurs des options du client +menu.customer-options-values-create=Créer une valeur option d'option du client +menu.customer-options-set=Gérer les options possibles du client +menu.content=Gestion du contenu +menu.content-pages=Gérer les pages +menu.content-pages-create=Créer une page +menu.content-boxes-create=Créer une boîte +menu.content-boxes=Gérer les boîtes +menu.content-images=Gérer les images +menu.content-files=Gérer les fichiers +menu.payment=Paiement +menu.tax=Taxes de vente +menu.taxconfiguration=Configuration des taxes +menu.taxclass=Classes de taxes +menu.taxrates=Taux des taxes +menu.taxrates.rate=Taux +menu.taxrates.code=Code du taux de taxe +menu.taxrates.name=Nom de la taxe +menu.product.category=Asscoier aux catégories +menu.accounts-conf=Configuration des comptes +menu.email-conf=Configuration du courriel +menu.system-configurations=Configurations du système +menu.manufacturer-list=Liste des fabricants +menu.manufacturer-create=Créer un fabricant +menu.addaddress=Ajouter une nouvelle adresse +menu.editaddress=Changer l'adresse diff --git a/sm-shop/src/main/resources/profiles/cloud/database.properties b/sm-shop/src/main/resources/profiles/cloud/database.properties new file mode 100755 index 0000000000..96b66f7ca0 --- /dev/null +++ b/sm-shop/src/main/resources/profiles/cloud/database.properties @@ -0,0 +1,40 @@ +## +## db config +## + +#Need to run these commands before running shopizer - choose your username and password +#mysql>CREATE DATABASE SALESMANAGER; +#mysql>CREATE USER shopizer IDENTIFIED BY 'very-long-shopizer-password'; +#mysql>GRANT ALL ON SALESMANAGER.* TO shopizer; +#mysql>FLUSH PRIVILEGES; + +#MYSQL +#when connecting to docker compose from outside docker +#db.jdbcUrl=jdbc:mysql://0.0.0.0:3307/SALESMANAGER?autoReconnect=true&serverTimeZone=UTC&useUnicode=true&characterEncoding=UTF-8 + +#db.jdbcUrl=jdbc:mysql://shopizer-db:3306/SALESMANAGER?autoReconnect=true&serverTimeZone=UTC&useUnicode=true&characterEncoding=UTF-8 +#db.user=shopizer_db_user +#db.password=shopizer_db_password +db.driverClass=com.mysql.cj.jdbc.Driver +hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect + +#H2 +#db.jdbcUrl=jdbc\:h2\:file\:./SALESMANAGER;AUTOCOMMIT=OFF;;mv_store=false;INIT\=CREATE SCHEMA IF NOT EXISTS SALESMANAGER +#db.user=test +#db.password=password +#db.driverClass=org.h2.Driver +#hibernate.dialect=org.hibernate.dialect.H2Dialect + +db.show.sql=true +db.preferredTestQuery=SELECT 1 +db.schema=SALESMANAGER +hibernate.hbm2ddl.auto=update + + + +## +## configuration pooling base de donn\uFFFDes +## +db.initialPoolSize=8 +db.minPoolSize=8 +db.maxPoolSize=15 \ No newline at end of file diff --git a/sm-shop/src/main/resources/profiles/dependency/database.properties b/sm-shop/src/main/resources/profiles/dependency/database.properties new file mode 100644 index 0000000000..f689df7c85 --- /dev/null +++ b/sm-shop/src/main/resources/profiles/dependency/database.properties @@ -0,0 +1,34 @@ +## +## db config +## + +#Need to run these commands before running shopizer - choose your username and password +#mysql>CREATE DATABASE SALESMANAGER; +#mysql>CREATE USER shopizer IDENTIFIED BY 'very-long-shopizer-password'; +#mysql>GRANT ALL ON SALESMANAGER.* TO shopizer; +#mysql>FLUSH PRIVILEGES; + +#MYSQL +#when connecting to docker compose from outside docker +#db.jdbcUrl=jdbc:mysql://0.0.0.0:3307/SALESMANAGER?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8 + +#db.jdbcUrl=jdbc:mysql://shopizer-db:3306/SALESMANAGER?autoReconnect=true&serverTimeZone=UTC&useUnicode=true&characterEncoding=UTF-8 +#db.user=shopizer_db_user +#db.password=shopizer_db_password +db.driverClass=com.mysql.cj.jdbc.Driver +hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect + + +db.show.sql=true +db.preferredTestQuery=SELECT 1 +db.schema=SALESMANAGER +hibernate.hbm2ddl.auto=update + + + +## +## configuration pooling base de donn\uFFFDes +## +db.initialPoolSize=4 +db.minPoolSize=4 +db.maxPoolSize=8 \ No newline at end of file diff --git a/sm-shop/src/main/resources/profiles/docker/database.properties b/sm-shop/src/main/resources/profiles/docker/database.properties new file mode 100755 index 0000000000..2e440413e9 --- /dev/null +++ b/sm-shop/src/main/resources/profiles/docker/database.properties @@ -0,0 +1,21 @@ + +#H2 +db.jdbcUrl=jdbc\:h2\:file\:./SALESMANAGER;AUTOCOMMIT=OFF;;mv_store=false;INIT\=CREATE SCHEMA IF NOT EXISTS SALESMANAGER +db.user=test +db.password=password +db.driverClass=org.h2.Driver +hibernate.dialect=org.hibernate.dialect.H2Dialect + +db.show.sql=true +db.preferredTestQuery=SELECT 1 +db.schema=SALESMANAGER +hibernate.hbm2ddl.auto=update + + + +## +## configuration pooling base de données +## +db.initialPoolSize=4 +db.minPoolSize=4 +db.maxPoolSize=8 \ No newline at end of file diff --git a/sm-shop/src/main/resources/profiles/gcp/database.properties b/sm-shop/src/main/resources/profiles/gcp/database.properties new file mode 100755 index 0000000000..66be3d11be --- /dev/null +++ b/sm-shop/src/main/resources/profiles/gcp/database.properties @@ -0,0 +1,28 @@ + +#Need to run these commands before running shopizer - choose your username and password +#mysql>CREATE DATABASE SALESMANAGER; +#mysql>CREATE USER shopizer IDENTIFIED BY 'very-long-shopizer-password'; +#mysql>GRANT ALL ON SALESMANAGER.* TO shopizer; +#mysql>FLUSH PRIVILEGES; + +#MYSQL +db.jdbcUrl=jdbc:mysql://:3306/SALESMANAGER?autoReconnect=true&serverTimeZone=UTC&&useUnicode=true&characterEncoding=UTF-8 +db.user=shopizer +db.password= +db.driverClass=com.mysql.cj.jdbc.Driver +hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect + + +db.show.sql=true +db.preferredTestQuery=SELECT 1 +db.schema=SALESMANAGER +hibernate.hbm2ddl.auto=update + + + +## +## db pool config +## +db.initialPoolSize=4 +db.minPoolSize=4 +db.maxPoolSize=8 \ No newline at end of file diff --git a/sm-shop/src/main/resources/profiles/local/database.properties b/sm-shop/src/main/resources/profiles/local/database.properties new file mode 100755 index 0000000000..1eeca6d466 --- /dev/null +++ b/sm-shop/src/main/resources/profiles/local/database.properties @@ -0,0 +1,31 @@ +## +## db config +## + +#Need to run these commands before running shopizer - choose your username and password +#mysql>CREATE DATABASE SALESMANAGER; +#mysql>CREATE USER shopizer IDENTIFIED BY 'very-long-shopizer-password'; +#mysql>GRANT ALL ON SALESMANAGER.* TO shopizer; +#mysql>FLUSH PRIVILEGES; + + +#MYSQL +db.jdbcUrl=jdbc:mysql://127.0.0.1:3306/SALESMANAGER?#autoReconnect=true&useUnicode=true&characterEncoding=UTF-8 +db.user=root +db.password=password +db.driverClass=com.mysql.cj.jdbc.Driver +hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect +db.preferredTestQuery=SELECT 1 + + +db.show.sql=false; +db.schema=SALESMANAGER +hibernate.hbm2ddl.auto=update + + +## +#configuration connection pool +## +db.initialPoolSize=4 +db.minPoolSize=4 +db.maxPoolSize=4 diff --git a/sm-shop/src/main/resources/profiles/mysql/database.properties b/sm-shop/src/main/resources/profiles/mysql/database.properties new file mode 100644 index 0000000000..31b04b1e10 --- /dev/null +++ b/sm-shop/src/main/resources/profiles/mysql/database.properties @@ -0,0 +1,30 @@ +## +## db config +## + +#Need to run these commands before running shopizer - choose your username and password +#mysql>CREATE DATABASE SALESMANAGER; +#mysql>CREATE USER shopizer IDENTIFIED BY 'very-long-shopizer-password'; +#mysql>GRANT ALL ON SALESMANAGER.* TO shopizer; +#mysql>FLUSH PRIVILEGES; + +#db.jdbcUrl=jdbc:mysql://localhost:3306/SALESMANAGER?autoReconnect=true&serverTimeZone=UTC&useUnicode=true&characterEncoding=UTF-8 +#db.user=shopizer_db_user +#db.password=shopizer_db_password +db.driverClass=com.mysql.cj.jdbc.Driver +hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect + + +db.show.sql=true +db.preferredTestQuery=SELECT 1 +db.schema=SALESMANAGER +hibernate.hbm2ddl.auto=update + + + +## +## configuration pooling base de donn\uFFFDes +## +db.initialPoolSize=8 +db.minPoolSize=8 +db.maxPoolSize=15 \ No newline at end of file diff --git a/sm-shop/src/main/resources/shopizer-properties.properties b/sm-shop/src/main/resources/shopizer-properties.properties new file mode 100755 index 0000000000..39c8c783d1 --- /dev/null +++ b/sm-shop/src/main/resources/shopizer-properties.properties @@ -0,0 +1,26 @@ +MULTIPLE_PRICE_AVAILABILITY=false +INDEX_PRODUCTS=true +PRODUCT_IMAGE_WIDTH_SIZE=1000 +PRODUCT_IMAGE_HEIGHT_SIZE=1100 +CROP_UPLOADED_IMAGES=false +PRODUCT_IMAGE_MAX_HEIGHT_SIZE=2000 +PRODUCT_IMAGE_MAX_WIDTH_SIZE=4000 +PRODUCT_IMAGE_MAX_SIZE=9000000 +IMAGE_FORMATS=jpg|png|gif +POPULATE_TEST_DATA=false +SHOP_SCHEME=http +CONTEXT_PATH= +URL_EXTENSION=.html +SEARCH_QUERY={"query":{"query_string":{"fields":["name^5","description","tags"],"query":"*%s*","use_dis_max":true}},"aggs":{"categories":{"terms":{"field":"categories"}}}} +AUTOCOMPLETE_QUERY={"size": 10,"query": {"match": {"keyword": {"query": "%s","operator":"and"}}}} +#deprecated use config.googleMapsKey +shopizer.googlemaps_key=NO +#keep this +shopizer.recapatcha_url=https://www.google.com/recaptcha/api/siteverify +PAYPAL_EXPRESSCHECKOUT_SANDBOX=https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token= +PAYPAL_EXPRESSCHECKOUT_PRODUCTION=https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token= +PAYPAL_EXPRESSCHECKOUT_REGULAR=_express-checkout&token= +PAYPAL_EXPRESSCHECKOUT_MOBILE=_express-checkout-mobile&token= +ORDER_EMAIL_API=true +VALIDATE_CREDIT_CARD=false +MAIL_SEND_ORDER_UPDATES=true diff --git a/sm-shop/src/main/resources/spring/shopizer-controllers.xml b/sm-shop/src/main/resources/spring/shopizer-controllers.xml new file mode 100755 index 0000000000..b950df2cf6 --- /dev/null +++ b/sm-shop/src/main/resources/spring/shopizer-controllers.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/jpeg + image/gif + image/png + image/webp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sm-shop/src/main/resources/spring/shopizer-servlet-context.xml b/sm-shop/src/main/resources/spring/shopizer-servlet-context.xml new file mode 100755 index 0000000000..7f9bd32001 --- /dev/null +++ b/sm-shop/src/main/resources/spring/shopizer-servlet-context.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + classpath:bundles/shopizer + classpath:bundles/messages + classpath:bundles/shipping + classpath:bundles/payment + + + + + + + + + + + + + \ No newline at end of file diff --git a/sm-shop/src/main/resources/static/favicon.ico b/sm-shop/src/main/resources/static/favicon.ico new file mode 100755 index 0000000000..c9a6e7d6f1 Binary files /dev/null and b/sm-shop/src/main/resources/static/favicon.ico differ diff --git a/sm-shop/src/main/resources/static/not-found.png b/sm-shop/src/main/resources/static/not-found.png new file mode 100644 index 0000000000..d032580aef Binary files /dev/null and b/sm-shop/src/main/resources/static/not-found.png differ diff --git a/sm-shop/src/main/resources/vault.properties b/sm-shop/src/main/resources/vault.properties new file mode 100755 index 0000000000..dc328ab513 --- /dev/null +++ b/sm-shop/src/main/resources/vault.properties @@ -0,0 +1,2 @@ +vault.uri=https://localhost:8200 +vault.token=5d482864-92ee-f4a6-82d4-58240453cb80 \ No newline at end of file diff --git a/sm-shop/src/test/java/com/salesmanager/test/shop/common/ServicesTestSupport.java b/sm-shop/src/test/java/com/salesmanager/test/shop/common/ServicesTestSupport.java new file mode 100755 index 0000000000..ffbb93ab4d --- /dev/null +++ b/sm-shop/src/test/java/com/salesmanager/test/shop/common/ServicesTestSupport.java @@ -0,0 +1,237 @@ +package com.salesmanager.test.shop.common; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.HttpStatus.OK; + +import java.math.BigDecimal; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.shop.application.ShopApplication; +import com.salesmanager.shop.model.catalog.category.Category; +import com.salesmanager.shop.model.catalog.category.CategoryDescription; +import com.salesmanager.shop.model.catalog.category.PersistableCategory; +import com.salesmanager.shop.model.catalog.manufacturer.ManufacturerDescription; +import com.salesmanager.shop.model.catalog.manufacturer.PersistableManufacturer; +import com.salesmanager.shop.model.catalog.product.PersistableProductPrice; +import com.salesmanager.shop.model.catalog.product.ProductDescription; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.model.catalog.product.product.PersistableProduct; +import com.salesmanager.shop.model.catalog.product.product.PersistableProductInventory; +import com.salesmanager.shop.model.catalog.product.product.ProductSpecification; +import com.salesmanager.shop.model.entity.Entity; +import com.salesmanager.shop.model.shoppingcart.PersistableShoppingCartItem; +import com.salesmanager.shop.model.shoppingcart.ReadableShoppingCart; +import com.salesmanager.shop.model.store.ReadableMerchantStore; +import com.salesmanager.shop.populator.customer.ReadableCustomerList; +import com.salesmanager.shop.store.security.AuthenticationRequest; +import com.salesmanager.shop.store.security.AuthenticationResponse; + +@SpringBootTest(classes = ShopApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) +@ExtendWith(SpringExtension.class) +public class ServicesTestSupport { + + @Autowired + protected TestRestTemplate testRestTemplate; + + protected HttpHeaders getHeader() { + return getHeader("admin@shopizer.com", "password"); + } + + protected HttpHeaders getHeader(final String userName, final String password) { + final ResponseEntity response = testRestTemplate.postForEntity("/api/v1/private/login", + new HttpEntity<>(new AuthenticationRequest(userName, password)), AuthenticationResponse.class); + final HttpHeaders headers = new HttpHeaders(); + headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8"))); + headers.add("Authorization", "Bearer " + response.getBody().getToken()); + return headers; + } + + public ReadableMerchantStore fetchStore() { + final HttpEntity httpEntity = new HttpEntity<>(getHeader()); + return testRestTemplate.exchange(String.format("/api/v1/store/%s", Constants.DEFAULT_STORE), HttpMethod.GET, + httpEntity, ReadableMerchantStore.class).getBody(); + + } + + public ReadableCustomerList fetchCustomers() { + final HttpEntity httpEntity = new HttpEntity<>(getHeader()); + return testRestTemplate + .exchange("/api/v1/private/customers", HttpMethod.GET, httpEntity, ReadableCustomerList.class) + .getBody(); + + } + + protected PersistableManufacturer manufacturer(String code) { + + PersistableManufacturer m = new PersistableManufacturer(); + m.setCode(code); + m.setOrder(0); + + ManufacturerDescription desc = new ManufacturerDescription(); + desc.setLanguage("en"); + desc.setName(code); + + m.getDescriptions().add(desc); + + return m; + + } + + protected PersistableCategory category(String code) { + + PersistableCategory newCategory = new PersistableCategory(); + newCategory.setCode(code); + newCategory.setSortOrder(1); + newCategory.setVisible(true); + newCategory.setDepth(1); + + CategoryDescription description = new CategoryDescription(); + description.setLanguage("en"); + description.setName(code); + + List descriptions = new ArrayList<>(); + descriptions.add(description); + + newCategory.setDescriptions(descriptions); + + return newCategory; + + } + + protected PersistableProduct product(String code) { + + PersistableProduct product = new PersistableProduct(); + + PersistableProductInventory inventory = new PersistableProductInventory(); + inventory.setQuantity(5); + inventory.setSku(code); + + final PersistableProductPrice productPrice = new PersistableProductPrice(); + productPrice.setDefaultPrice(true); + + productPrice.setPrice(new BigDecimal(250)); + productPrice.setDiscountedPrice(new BigDecimal(125)); + + final List productPriceList = new ArrayList<>(); + productPriceList.add(productPrice); + + inventory.setPrice(productPrice); + product.setInventory(inventory); + + + ProductDescription description = new ProductDescription(); + description.setName(code); + description.setLanguage("en"); + + product.getDescriptions().add(description); + + return product; + + } + + protected ReadableProduct sampleProduct(String code) { + + final PersistableCategory newCategory = new PersistableCategory(); + newCategory.setCode(code); + newCategory.setSortOrder(1); + newCategory.setVisible(true); + newCategory.setDepth(4); + + final Category parent = new Category(); + + newCategory.setParent(parent); + + final CategoryDescription description = new CategoryDescription(); + description.setLanguage("en"); + description.setName("test-cat"); + description.setFriendlyUrl("test-cat"); + description.setTitle("test-cat"); + + final List descriptions = new ArrayList<>(); + descriptions.add(description); + + newCategory.setDescriptions(descriptions); + + final HttpEntity categoryEntity = new HttpEntity<>(newCategory, getHeader()); + + final ResponseEntity categoryResponse = testRestTemplate.postForEntity( + "/api/v1/private/category?store=" + Constants.DEFAULT_STORE, categoryEntity, PersistableCategory.class); + final PersistableCategory cat = categoryResponse.getBody(); + assertThat(categoryResponse.getStatusCode(), is(CREATED)); + assertNotNull(cat.getId()); + + final PersistableProduct product = this.product(code); + final ArrayList categories = new ArrayList<>(); + categories.add(cat); + product.setCategories(categories); + ProductSpecification specifications = new ProductSpecification(); + specifications.setManufacturer( + com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer.DEFAULT_MANUFACTURER); + product.setProductSpecifications(specifications); + product.setAvailable(true); + product.setPrice(BigDecimal.TEN); + product.setSku(code); + product.setQuantity(100); + /** + ProductDescription productDescription = new ProductDescription(); + productDescription.setDescription("TEST"); + productDescription.setName("TestName"); + productDescription.setLanguage("en"); + product.getDescriptions().add(productDescription); + **/ + + final HttpEntity entity = new HttpEntity<>(product, getHeader()); + + final ResponseEntity response = testRestTemplate.postForEntity( + "/api/v1/private/product?store=" + Constants.DEFAULT_STORE, entity, Entity.class); + assertThat(response.getStatusCode(), is(CREATED)); + + final HttpEntity httpEntity = new HttpEntity<>(getHeader()); + + String apiUrl = "/api/v1/product/" + response.getBody().getId(); + + ResponseEntity readableProduct = testRestTemplate.exchange(apiUrl, HttpMethod.GET, httpEntity, + ReadableProduct.class); + assertThat(readableProduct.getStatusCode(), is(OK)); + + return readableProduct.getBody(); + } + + protected ReadableShoppingCart sampleCart() { + + ReadableProduct product = sampleProduct("sampleCart"); + assertNotNull(product); + + PersistableShoppingCartItem cartItem = new PersistableShoppingCartItem(); + cartItem.setProduct(product.getSku()); + cartItem.setQuantity(1); + + final HttpEntity cartEntity = new HttpEntity<>(cartItem, getHeader()); + final ResponseEntity response = testRestTemplate + .postForEntity(String.format("/api/v1/cart/"), cartEntity, ReadableShoppingCart.class); + + assertNotNull(response); + assertThat(response.getStatusCode(), is(CREATED)); + + return response.getBody(); + } + +} diff --git a/sm-shop/src/test/java/com/salesmanager/test/shop/integration/cart/CartTestBean.java b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/cart/CartTestBean.java new file mode 100644 index 0000000000..f534138ac2 --- /dev/null +++ b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/cart/CartTestBean.java @@ -0,0 +1,30 @@ +package com.salesmanager.test.shop.integration.cart; + +import com.salesmanager.shop.model.catalog.product.ReadableProduct; + +import java.util.ArrayList; +import java.util.List; + +public class CartTestBean { + + private String cartId; + + private List products = new ArrayList<>(); + + public String getCartId() { + return cartId; + } + + void setCartId(String cartId) { + this.cartId = cartId; + } + + public void setProducts(List products) { + this.products = products; + } + + public List getProducts() { + return products; + } + +} diff --git a/sm-shop/src/test/java/com/salesmanager/test/shop/integration/cart/ShoppingCartAPIIntegrationTest.java b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/cart/ShoppingCartAPIIntegrationTest.java new file mode 100755 index 0000000000..b34310aeba --- /dev/null +++ b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/cart/ShoppingCartAPIIntegrationTest.java @@ -0,0 +1,229 @@ +package com.salesmanager.test.shop.integration.cart; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.HttpStatus.NOT_FOUND; +import static org.springframework.http.HttpStatus.NO_CONTENT; +import static org.springframework.http.HttpStatus.OK; + +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.salesmanager.shop.application.ShopApplication; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.model.shoppingcart.PersistableShoppingCartItem; +import com.salesmanager.shop.model.shoppingcart.ReadableShoppingCart; +import com.salesmanager.test.shop.common.ServicesTestSupport; + +@SpringBootTest(classes = ShopApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) +@ExtendWith(SpringExtension.class) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class ShoppingCartAPIIntegrationTest extends ServicesTestSupport { + + @Autowired + private TestRestTemplate testRestTemplate; + + private static CartTestBean data = new CartTestBean(); + + + /** + * Add an Item & Create cart, would give HTTP 201 & 1 qty + * + * @throws Exception + */ + @Test + @Order(1) + public void addToCart() throws Exception { + + ReadableProduct product = sampleProduct("addToCart"); + assertNotNull(product); + data.getProducts().add(product); + + PersistableShoppingCartItem cartItem = new PersistableShoppingCartItem(); + cartItem.setProduct(product.getSku()); + cartItem.setQuantity(1); + + final HttpEntity cartEntity = new HttpEntity<>(cartItem, getHeader()); + final ResponseEntity response = testRestTemplate.postForEntity(String.format("/api/v1/cart/"), cartEntity, ReadableShoppingCart.class); + + data.setCartId(response.getBody().getCode()); + + assertNotNull(response); + assertThat(response.getStatusCode(), is(CREATED)); + assertEquals(response.getBody().getQuantity(), 1); + + } + + /** + * Add an second Item to existing Cart, should give HTTP 201 & 2 qty + * + * @throws Exception + */ + @Test + @Order(2) + public void addSecondToCart() throws Exception { + + ReadableProduct product = sampleProduct("add2Cart2"); + assertNotNull(product); + data.getProducts().add(product); + + PersistableShoppingCartItem cartItem = new PersistableShoppingCartItem(); + cartItem.setProduct(product.getSku()); + cartItem.setQuantity(1); + + final HttpEntity cartEntity = new HttpEntity<>(cartItem, getHeader()); + final ResponseEntity response = testRestTemplate.exchange(String.format("/api/v1/cart/" + String.valueOf(data.getCartId())), + HttpMethod.PUT, + cartEntity, + ReadableShoppingCart.class); + + assertNotNull(response); + assertThat(response.getStatusCode(), is(CREATED)); + assertEquals(response.getBody().getQuantity(), 2); + } + + /** + * Add an other item to cart which then does not exist which should return HTTP 404 + * + * @throws Exception + */ + @Test + @Order(3) + public void addToWrongToCartId() throws Exception { + + ReadableProduct product = sampleProduct("add3Cart"); + assertNotNull(product); + data.getProducts().add(product); + + PersistableShoppingCartItem cartItem = new PersistableShoppingCartItem(); + cartItem.setProduct(product.getSku()); + cartItem.setQuantity(1); + + final HttpEntity cartEntity = new HttpEntity<>(cartItem, getHeader()); + final ResponseEntity response = testRestTemplate.exchange(String.format("/api/v1/cart/" + data.getCartId() + "breakIt"), + HttpMethod.PUT, + cartEntity, + ReadableShoppingCart.class); + + assertNotNull(response); + assertThat(response.getStatusCode(), is(NOT_FOUND)); + data.getProducts().remove(product); + } + + + /** + * Update cart items with qty 2 (1) on existing items & adding new item with qty 1 which gives result 2x2+1 = 5 + * + * @throws Exception + */ + @Test + @Order(4) + public void updateMultiWCartId() throws Exception { + + PersistableShoppingCartItem cartItem1 = new PersistableShoppingCartItem(); + cartItem1.setProduct(data.getProducts().get(0).getSku()); + cartItem1.setQuantity(2); + + PersistableShoppingCartItem cartItem2 = new PersistableShoppingCartItem(); + cartItem2.setProduct(data.getProducts().get(1).getSku()); + cartItem2.setQuantity(2); + + + PersistableShoppingCartItem[] productsQtyUpdates = {cartItem1, cartItem2}; + + + final HttpEntity cartEntity = new HttpEntity<>(productsQtyUpdates, getHeader()); + final ResponseEntity response = testRestTemplate.exchange(String.format("/api/v1/cart/" + data.getCartId() + + "/multi"), + HttpMethod.POST, + cartEntity, + ReadableShoppingCart.class); + + assertNotNull(response); + assertThat(response.getStatusCode(), is(CREATED)); + assertEquals(4, response.getBody().getQuantity()); + } + + /** + * Update cart with qnt 0 on one cart item which gives 3 qty left + * + * @throws Exception + */ + @Test + @Order(5) + public void updateMultiWZeroOnOneProd() throws Exception { + + PersistableShoppingCartItem cartItem1 = new PersistableShoppingCartItem(); + cartItem1.setProduct(data.getProducts().get(0).getSku()); + cartItem1.setQuantity(0); + + PersistableShoppingCartItem[] productsQtyUpdates = {cartItem1}; + + + final HttpEntity cartEntity = new HttpEntity<>(productsQtyUpdates, getHeader()); + final ResponseEntity response = testRestTemplate.exchange(String.format("/api/v1/cart/" + data.getCartId() + + "/multi"), + HttpMethod.POST, + cartEntity, + ReadableShoppingCart.class); + + assertNotNull(response); + assertThat(response.getStatusCode(), is(CREATED)); + assertEquals(2, response.getBody().getQuantity()); + } + + /** + * Delete cartitem from cart, should return 204 / no content + * + * @throws Exception + */ + @Test + @Order(6) + public void deleteCartItem() throws Exception { + + final ResponseEntity response = + testRestTemplate.exchange(String.format("/api/v1/cart/" + data.getCartId() + "/product/" + String.valueOf(data.getProducts().get(1).getId())), + HttpMethod.DELETE, + null, + ReadableShoppingCart.class); + + assertNotNull(response); + assertThat(response.getStatusCode(), is(NO_CONTENT)); + assertNull(response.getBody()); + } + + /** + * Delete cartitem from cart with body set to true which gives remaining cart content, should return 200 / ok + * + * @throws Exception + */ + @Test + @Order(7) + public void deleteCartItemWithBody() throws Exception { + + final ResponseEntity response = + testRestTemplate.exchange(String.format("/api/v1/cart/" + data.getCartId() + "/product/" + String.valueOf(data.getProducts().get(1).getSku()) + "?body=true"), + HttpMethod.DELETE, + null, + ReadableShoppingCart.class); + + assertNotNull(response); + assertThat(response.getStatusCode(), is(OK)); + } + +} diff --git a/sm-shop/src/test/java/com/salesmanager/test/shop/integration/category/CategoryManagementAPIIntegrationTest.java b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/category/CategoryManagementAPIIntegrationTest.java new file mode 100755 index 0000000000..6e08e2fff0 --- /dev/null +++ b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/category/CategoryManagementAPIIntegrationTest.java @@ -0,0 +1,426 @@ +package com.salesmanager.test.shop.integration.category; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.HttpStatus.OK; +import java.util.ArrayList; +import java.util.List; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.shop.application.ShopApplication; +import com.salesmanager.shop.model.catalog.category.Category; +import com.salesmanager.shop.model.catalog.category.CategoryDescription; +import com.salesmanager.shop.model.catalog.category.PersistableCategory; +import com.salesmanager.shop.model.catalog.category.ReadableCategory; +import com.salesmanager.shop.model.catalog.category.ReadableCategoryList; +import com.salesmanager.shop.model.catalog.manufacturer.PersistableManufacturer; +import com.salesmanager.shop.model.catalog.manufacturer.ReadableManufacturer; +import com.salesmanager.shop.model.catalog.product.product.PersistableProduct; +import com.salesmanager.shop.model.catalog.product.product.ProductSpecification; +import com.salesmanager.test.shop.common.ServicesTestSupport; + +@SpringBootTest(classes = ShopApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) +@RunWith(SpringRunner.class) +public class CategoryManagementAPIIntegrationTest extends ServicesTestSupport { + + @Autowired + private TestRestTemplate testRestTemplate; + + + + /** + * Read - GET a category by id + * + * @throws Exception + */ + @Test + public void getCategory() throws Exception { + final HttpEntity httpEntity = new HttpEntity<>(getHeader()); + + final ResponseEntity response = testRestTemplate.exchange(String.format("/api/v1/category/"), HttpMethod.GET, + httpEntity, ReadableCategoryList.class); + if (response.getStatusCode() != HttpStatus.OK) { + throw new Exception(response.toString()); + } else { + final List categories = response.getBody().getCategories(); + assertNotNull(categories); + } + } + + /** + * Creates - POST a category for a given store + * + * @throws Exception + */ + + @Test + public void postCategory() throws Exception { + + PersistableCategory newCategory = new PersistableCategory(); + newCategory.setCode("javascript"); + newCategory.setSortOrder(1); + newCategory.setVisible(true); + newCategory.setDepth(4); + + Category parent = new Category(); + + newCategory.setParent(parent); + + CategoryDescription description = new CategoryDescription(); + description.setLanguage("en"); + description.setName("Javascript"); + description.setFriendlyUrl("javascript"); + description.setTitle("Javascript"); + + List descriptions = new ArrayList<>(); + descriptions.add(description); + + newCategory.setDescriptions(descriptions); + + final ObjectWriter writer = new ObjectMapper().writer().withDefaultPrettyPrinter(); + final String json = writer.writeValueAsString(newCategory); + + HttpEntity entity = new HttpEntity<>(json, getHeader()); + + ResponseEntity response = testRestTemplate.postForEntity("/api/v1/private/category", entity, PersistableCategory.class); + PersistableCategory cat = (PersistableCategory) response.getBody(); + assertThat(response.getStatusCode(), is(CREATED)); + assertNotNull(cat.getId()); + + } + + @Test + public void putCategory() throws Exception { + + //create + PersistableCategory newCategory = new PersistableCategory(); + newCategory.setCode("angular"); + newCategory.setSortOrder(1); + newCategory.setVisible(true); + newCategory.setDepth(4); + + + CategoryDescription description = new CategoryDescription(); + description.setLanguage("en"); + description.setName("angular"); + description.setFriendlyUrl("angular"); + description.setTitle("angular"); + + List descriptions = new ArrayList<>(); + descriptions.add(description); + + newCategory.setDescriptions(descriptions); + + final ObjectWriter writer = new ObjectMapper().writer().withDefaultPrettyPrinter(); + final String json = writer.writeValueAsString(newCategory); + + final HttpEntity entity = new HttpEntity<>(json, getHeader()); + //create category + final ResponseEntity response = testRestTemplate.postForEntity("/api/v1/private/category", entity, PersistableCategory.class); + final PersistableCategory cat = (PersistableCategory) response.getBody(); + assertThat(response.getStatusCode(), is(CREATED)); + assertNotNull(cat.getId()); + + HttpEntity httpEntity = new HttpEntity<>(getHeader()); + + final ResponseEntity readableQuery = testRestTemplate.exchange(String.format("/api/v1/category/" + cat.getId()), HttpMethod.GET, + httpEntity, ReadableCategory.class); + + assertThat(readableQuery.getStatusCode(), is(OK)); + + ReadableCategory readableCategory = readableQuery.getBody(); + + newCategory = new PersistableCategory(); + newCategory.setCode("angular"); + newCategory.setVisible(true); + newCategory.setDepth(4); + newCategory.setSortOrder(2); + description = new CategoryDescription(); + description.setLanguage("en"); + description.setName("angular"); + description.setFriendlyUrl("angular"); + description.setTitle("angular"); + + descriptions = new ArrayList<>(); + descriptions.add(description); + + newCategory.setDescriptions(descriptions); + + + HttpEntity requestUpdate = new HttpEntity<>(newCategory, getHeader()); + + ResponseEntity resp = testRestTemplate.exchange("/api/v1/private/category/" + cat.getId(), HttpMethod.PUT, requestUpdate, Void.class); + assertThat(resp.getStatusCode(), is(OK)); + + //update + + } + + @Test + public void postComplexCategory() throws Exception { + + /** Dining room **/ + final PersistableCategory dining = new PersistableCategory(); + dining.setCode("diningroom"); + dining.setSortOrder(0); + dining.setVisible(true); + + CategoryDescription endescription = new CategoryDescription(); + endescription.setLanguage("en"); + endescription.setName("Dining room"); + endescription.setFriendlyUrl("dining-room"); + endescription.setTitle("Dining room"); + + CategoryDescription frdescription = new CategoryDescription(); + frdescription.setLanguage("fr"); + frdescription.setName("Salle à manger"); + frdescription.setFriendlyUrl("salle-a-manger"); + frdescription.setTitle("Salle à manger"); + + List descriptions = new ArrayList<>(); + descriptions.add(endescription); + descriptions.add(frdescription); + + dining.setDescriptions(descriptions); + + final Category diningParent = new Category(); + diningParent.setCode(dining.getCode()); + + /** armoire **/ + final PersistableCategory armoire = new PersistableCategory(); + armoire.setCode("armoire"); + armoire.setSortOrder(1); + armoire.setVisible(true); + + armoire.setParent(diningParent); + + endescription = new CategoryDescription(); + endescription.setLanguage("en"); + endescription.setName("Armoires"); + endescription.setFriendlyUrl("armoires"); + endescription.setTitle("Armoires"); + + frdescription = new CategoryDescription(); + frdescription.setLanguage("fr"); + frdescription.setName("Armoire"); + frdescription.setFriendlyUrl("armoires"); + frdescription.setTitle("Armoires"); + + descriptions = new ArrayList<>(); + descriptions.add(endescription); + descriptions.add(frdescription); + + armoire.setDescriptions(descriptions); + dining.getChildren().add(armoire); + + /** benches **/ + final PersistableCategory bench = new PersistableCategory(); + bench.setCode("bench"); + bench.setSortOrder(4); + bench.setVisible(true); + + bench.setParent(diningParent); + + endescription = new CategoryDescription(); + endescription.setLanguage("en"); + endescription.setName("Benches"); + endescription.setFriendlyUrl("benches"); + endescription.setTitle("Benches"); + + frdescription = new CategoryDescription(); + frdescription.setLanguage("fr"); + frdescription.setName("Bancs"); + frdescription.setFriendlyUrl("bancs"); + frdescription.setTitle("Bancs"); + + descriptions = new ArrayList<>(); + descriptions.add(endescription); + descriptions.add(frdescription); + + bench.setDescriptions(descriptions); + dining.getChildren().add(bench); + + /** Living room **/ + final PersistableCategory living = new PersistableCategory(); + living.setCode("livingroom"); + living.setSortOrder(2); + living.setVisible(true); + + endescription = new CategoryDescription(); + endescription.setLanguage("en"); + endescription.setName("Living room"); + endescription.setFriendlyUrl("living-room"); + endescription.setTitle("Living room"); + + frdescription = new CategoryDescription(); + frdescription.setLanguage("fr"); + frdescription.setName("Salon"); + frdescription.setFriendlyUrl("salon"); + frdescription.setTitle("Salon"); + + descriptions = new ArrayList<>(); + descriptions.add(endescription); + descriptions.add(frdescription); + + living.setDescriptions(descriptions); + + /** lounge **/ + + final PersistableCategory lounge = new PersistableCategory(); + lounge.setCode("lounge"); + lounge.setSortOrder(3); + lounge.setVisible(true); + + final Category livingParent = living; + lounge.setParent(livingParent); + + endescription = new CategoryDescription(); + endescription.setLanguage("en"); + endescription.setName("Lounge"); + endescription.setFriendlyUrl("lounge"); + endescription.setTitle("Lounge"); + + frdescription = new CategoryDescription(); + frdescription.setLanguage("fr"); + frdescription.setName("Divan"); + frdescription.setFriendlyUrl("divan"); + frdescription.setTitle("Divan"); + + descriptions = new ArrayList<>(); + descriptions.add(endescription); + descriptions.add(frdescription); + + lounge.setDescriptions(descriptions); + living.getChildren().add(lounge); + + final ObjectWriter writer = new ObjectMapper().writer().withDefaultPrettyPrinter(); + final String json = writer.writeValueAsString(dining); + + //System.out.println(json); + + final HttpEntity entity = new HttpEntity<>(json, getHeader()); + + final int sizeBefore = testRestTemplate.exchange(String.format("/api/v1/category"), HttpMethod.GET, + new HttpEntity<>(getHeader()), ReadableCategoryList.class).getBody().getCategories().size(); + + final ResponseEntity response = testRestTemplate.postForEntity("/api/v1/private/category", entity, PersistableCategory.class); + + final PersistableCategory cat = (PersistableCategory) response.getBody(); + assertThat(response.getStatusCode(), is(CREATED)); + assertNotNull(cat.getId()); + + + + } + + @Test + public void deleteCategory() throws Exception { + + final HttpEntity httpEntity = new HttpEntity<>(getHeader()); + + testRestTemplate.exchange("/services/DEFAULT/category/100", HttpMethod.DELETE, httpEntity, Category.class); + } + + @Test + public void manufacturerForItemsInCategory() throws Exception { + + ObjectWriter writer = new ObjectMapper().writer().withDefaultPrettyPrinter(); + + //create first manufacturer + PersistableManufacturer m1 = super.manufacturer("BRAND1"); + + String json = writer.writeValueAsString(m1); + HttpEntity entity = new HttpEntity<>(json, getHeader()); + + @SuppressWarnings("rawtypes") + ResponseEntity response = testRestTemplate.postForEntity("/api/v1/private/manufacturer", entity, PersistableManufacturer.class); + assertThat(response.getStatusCode(), is(CREATED)); + + //create second manufacturer + PersistableManufacturer m2 = super.manufacturer("BRAND2"); + json = writer.writeValueAsString(m2); + entity = new HttpEntity<>(json, getHeader()); + + response = testRestTemplate.postForEntity("/api/v1/private/manufacturer", entity, PersistableManufacturer.class); + assertThat(response.getStatusCode(), is(CREATED)); + + //create category + PersistableCategory category = super.category("TEST"); + Category cat = new Category();//to be used in product + cat.setCode("TEST"); + + json = writer.writeValueAsString(category); + entity = new HttpEntity<>(json, getHeader()); + + @SuppressWarnings("rawtypes") + ResponseEntity categoryResponse = testRestTemplate.postForEntity("/api/v1/private/category", entity, PersistableCategory.class); + assertThat(categoryResponse.getStatusCode(), is(CREATED)); + final PersistableCategory persistable = (PersistableCategory) categoryResponse.getBody(); + + Long id = persistable.getId(); + + //create first item + + PersistableProduct product1 = super.product("PRODUCT1"); + product1.getCategories().add(cat); + + + ProductSpecification specifications = new ProductSpecification(); + specifications.setManufacturer("BRAND1"); + product1.setProductSpecifications(specifications); + + json = writer.writeValueAsString(product1); + entity = new HttpEntity<>(json, getHeader()); + + response = testRestTemplate.postForEntity("/api/v1/private/product?store=" + Constants.DEFAULT_STORE, entity, PersistableProduct.class); + assertThat(response.getStatusCode(), is(CREATED)); + + //create second item + + PersistableProduct product2 = super.product("PRODUCT2"); + product2.getCategories().add(cat); + + + specifications = new ProductSpecification(); + specifications.setManufacturer("BRAND2"); + product2.setProductSpecifications(specifications); + + json = writer.writeValueAsString(product2); + entity = new HttpEntity<>(json, getHeader()); + + response = testRestTemplate.postForEntity("/api/v1/private/product?store=" + Constants.DEFAULT_STORE, entity, PersistableProduct.class); + assertThat(response.getStatusCode(), is(CREATED)); + + entity = new HttpEntity<>(getHeader()); + + //get manufacturers in category + @SuppressWarnings("rawtypes") + ResponseEntity manufacturers = testRestTemplate.exchange(String.format("/api/v1/category/" + id + "/manufacturer"), HttpMethod.GET, entity, List.class); + assertThat(manufacturers.getStatusCode(), is(OK)); + + @SuppressWarnings("unchecked") + List manufacturerList = manufacturers.getBody(); + + + //assertFalse(manufacturerList.isEmpty()); + + + + + } + +} \ No newline at end of file diff --git a/sm-shop/src/test/java/com/salesmanager/test/shop/integration/customer/CustomerRegistrationIntegrationTest.java b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/customer/CustomerRegistrationIntegrationTest.java new file mode 100755 index 0000000000..c4e71634bd --- /dev/null +++ b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/customer/CustomerRegistrationIntegrationTest.java @@ -0,0 +1,57 @@ +package com.salesmanager.test.shop.integration.customer; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.springframework.http.HttpStatus.OK; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.http.HttpEntity; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.model.customer.CustomerGender; +import com.salesmanager.shop.application.ShopApplication; +import com.salesmanager.shop.model.customer.PersistableCustomer; +import com.salesmanager.shop.model.customer.address.Address; +import com.salesmanager.shop.store.security.AuthenticationRequest; +import com.salesmanager.shop.store.security.AuthenticationResponse; +import com.salesmanager.test.shop.common.ServicesTestSupport; + +@SpringBootTest(classes = ShopApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) +@RunWith(SpringRunner.class) +public class CustomerRegistrationIntegrationTest extends ServicesTestSupport { + + @Test + public void registerCustomer() { + + + final PersistableCustomer testCustomer = new PersistableCustomer(); + testCustomer.setEmailAddress("customer1@test.com"); + testCustomer.setPassword("clear123"); + testCustomer.setGender(CustomerGender.M.name()); + testCustomer.setLanguage("en"); + final Address billing = new Address(); + billing.setFirstName("customer1"); + billing.setLastName("ccstomer1"); + billing.setCountry("BE"); + testCustomer.setBilling(billing); + testCustomer.setStoreCode(Constants.DEFAULT_STORE); + final HttpEntity entity = new HttpEntity<>(testCustomer, getHeader()); + + final ResponseEntity response = testRestTemplate.postForEntity("/api/v1/customer/register", entity, PersistableCustomer.class); + assertThat(response.getStatusCode(), is(OK)); + + // created customer can login + + final ResponseEntity loginResponse = testRestTemplate.postForEntity("/api/v1/customer/login", new HttpEntity<>(new AuthenticationRequest("customer1@test.com", "clear123")), + AuthenticationResponse.class); + assertThat(loginResponse.getStatusCode(), is(OK)); + assertNotNull(loginResponse.getBody().getToken()); + + } + +} \ No newline at end of file diff --git a/sm-shop/src/test/java/com/salesmanager/test/shop/integration/order/OrderApiIntegrationTest.java b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/order/OrderApiIntegrationTest.java new file mode 100644 index 0000000000..e075fd7de1 --- /dev/null +++ b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/order/OrderApiIntegrationTest.java @@ -0,0 +1,25 @@ +package com.salesmanager.test.shop.integration.order; + +import org.junit.Ignore; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.web.client.TestRestTemplate; + +import com.salesmanager.shop.model.shoppingcart.ReadableShoppingCart; +import com.salesmanager.test.shop.common.ServicesTestSupport; + + +@Ignore +public class OrderApiIntegrationTest extends ServicesTestSupport { + + @Autowired + private TestRestTemplate testRestTemplate; + + public void createOrder() throws Exception { + + //create cart + ReadableShoppingCart cart = super.sampleCart(); + + //create order + } + +} diff --git a/sm-shop/src/test/java/com/salesmanager/test/shop/integration/product/ProductManagementAPIIntegrationTest.java b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/product/ProductManagementAPIIntegrationTest.java new file mode 100755 index 0000000000..eef6f58c68 --- /dev/null +++ b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/product/ProductManagementAPIIntegrationTest.java @@ -0,0 +1,407 @@ +package com.salesmanager.test.shop.integration.product; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.springframework.http.HttpStatus.CREATED; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestTemplate; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.core.model.catalog.product.attribute.ProductOptionType; +import com.salesmanager.shop.application.ShopApplication; +import com.salesmanager.shop.model.catalog.category.Category; +import com.salesmanager.shop.model.catalog.category.CategoryDescription; +import com.salesmanager.shop.model.catalog.category.PersistableCategory; +import com.salesmanager.shop.model.catalog.manufacturer.Manufacturer; +import com.salesmanager.shop.model.catalog.product.PersistableProductPrice; +import com.salesmanager.shop.model.catalog.product.PersistableProductReview; +import com.salesmanager.shop.model.catalog.product.ProductDescription; +import com.salesmanager.shop.model.catalog.product.ReadableProduct; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductOption; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductOptionValue; +import com.salesmanager.shop.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription; +import com.salesmanager.shop.model.catalog.product.product.PersistableProduct; +import com.salesmanager.shop.model.catalog.product.product.PersistableProductInventory; +import com.salesmanager.shop.model.catalog.product.product.ProductSpecification; +import com.salesmanager.test.shop.common.ServicesTestSupport; + +@SpringBootTest(classes = ShopApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) +@RunWith(SpringRunner.class) +public class ProductManagementAPIIntegrationTest extends ServicesTestSupport { + + private RestTemplate restTemplate; + + private Long testCategoryID; + + private Long testProductID; + + @Test + public void createProductWithCategory() throws Exception { + + + final PersistableCategory newCategory = new PersistableCategory(); + newCategory.setCode("test-cat"); + newCategory.setSortOrder(1); + newCategory.setVisible(true); + newCategory.setDepth(4); + + final Category parent = new Category(); + + newCategory.setParent(parent); + + final CategoryDescription description = new CategoryDescription(); + description.setLanguage("en"); + description.setName("test-cat"); + description.setFriendlyUrl("test-cat"); + description.setTitle("test-cat"); + + final List descriptions = new ArrayList<>(); + descriptions.add(description); + + newCategory.setDescriptions(descriptions); + + final HttpEntity categoryEntity = new HttpEntity<>(newCategory, getHeader()); + + final ResponseEntity categoryResponse = testRestTemplate.postForEntity( + "/api/v1/private/category?store=" + Constants.DEFAULT_STORE, categoryEntity, PersistableCategory.class); + final PersistableCategory cat = categoryResponse.getBody(); + assertThat(categoryResponse.getStatusCode(), is(CREATED)); + assertNotNull(cat.getId()); + + final PersistableProduct product = super.product("PRODUCT12"); + final ArrayList categories = new ArrayList<>(); + categories.add(cat); + product.setCategories(categories); + ProductSpecification specifications = new ProductSpecification(); + specifications.setManufacturer( + com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer.DEFAULT_MANUFACTURER); + product.setProductSpecifications(specifications); + product.setPrice(BigDecimal.TEN); + product.setSku("123ABC"); + final HttpEntity entity = new HttpEntity<>(product, getHeader()); + + final ResponseEntity response = testRestTemplate.postForEntity( + "/api/v1/private/product?store=" + Constants.DEFAULT_STORE, entity, PersistableProduct.class); + assertThat(response.getStatusCode(), is(CREATED)); + } + + /** + * Creates a ProductReview requires an existing Customer and an existing + * Product + * + * @throws Exception + */ + @Ignore + @Test + public void createProductReview() throws Exception { + + final PersistableProductReview review = new PersistableProductReview(); + review.setCustomerId(1L); + + review.setProductId(1L); + review.setLanguage("en"); + review.setRating(2D);// rating is on 5 + review.setDescription( + "Not as good as expected. From what i understood that was supposed to be premium quality but unfortunately i had to return the item after one week... Verry disapointed !"); + review.setDate("2021-06-06"); + final HttpEntity entity = new HttpEntity<>(review, getHeader()); + + final ResponseEntity response = testRestTemplate.postForEntity( + "/api/v1/private/products/1/reviews?store=" + Constants.DEFAULT_STORE, entity, + PersistableProductReview.class); + + final PersistableProductReview rev = response.getBody(); + assertThat(response.getStatusCode(), is(CREATED)); + assertNotNull(rev.getId()); + + } + + /** + * Creates a product option value that can be used to create a product + * attribute when creating a new product + * + * @throws Exception + */ + @Test + @Ignore + public void createOptionValue() throws Exception { + + final ProductOptionValueDescription description = new ProductOptionValueDescription(); + description.setLanguage("en"); + description.setName("Red"); + + final List descriptions = new ArrayList<>(); + descriptions.add(description); + + final PersistableProductOptionValue optionValue = new PersistableProductOptionValue(); + optionValue.setOrder(1); + optionValue.setCode("colorred"); + optionValue.setDescriptions(descriptions); + + final ObjectWriter writer = new ObjectMapper().writer().withDefaultPrettyPrinter(); + final String json = writer.writeValueAsString(optionValue); + + System.out.println(json); + + /** + * { "descriptions" : [ { "name" : "Red", "description" : null, + * "friendlyUrl" : null, "keyWords" : null, "highlights" : null, + * "metaDescription" : null, "title" : null, "language" : "en", "id" : 0 + * } ], "order" : 1, "code" : "color-red", "id" : 0 } + */ + + restTemplate = new RestTemplate(); + + final HttpEntity entity = new HttpEntity<>(json, getHeader()); + + final ResponseEntity response = restTemplate.postForEntity( + "http://localhost:8080/sm-shop/services/private/DEFAULT/product/optionValue", entity, + PersistableProductOptionValue.class); + + final PersistableProductOptionValue opt = (PersistableProductOptionValue) response.getBody(); + System.out.println("New optionValue ID : " + opt.getId()); + + } + + /** + * Creates a new ProductOption + * + * @throws Exception + */ + @Test + @Ignore + public void createOption() throws Exception { + + final ProductOptionDescription description = new ProductOptionDescription(); + description.setLanguage("en"); + description.setName("Color"); + + final List descriptions = new ArrayList<>(); + descriptions.add(description); + + final PersistableProductOption option = new PersistableProductOption(); + option.setOrder(1); + option.setCode("color"); + option.setType(ProductOptionType.Select.name()); + option.setDescriptions(descriptions); + + final ObjectWriter writer = new ObjectMapper().writer().withDefaultPrettyPrinter(); + final String json = writer.writeValueAsString(option); + + System.out.println(json); + + /** + * { "descriptions" : [ { "name" : "Color", "description" : null, + * "friendlyUrl" : null, "keyWords" : null, "highlights" : null, + * "metaDescription" : null, "title" : null, "language" : "en", "id" : 0 + * } ], "type" : SELECT, "order" : 1, "code" : "color", "id" : 0 } + */ + + restTemplate = new RestTemplate(); + + final HttpEntity entity = new HttpEntity<>(json, getHeader()); + + final ResponseEntity response = restTemplate.postForEntity( + "http://localhost:8080/sm-shop/services/private/DEFAULT/product/option", entity, + PersistableProductOption.class); + + final PersistableProductOption opt = (PersistableProductOption) response.getBody(); + System.out.println("New option ID : " + opt.getId()); + + } + + @Test + @Ignore + public void getProducts() throws Exception { + restTemplate = new RestTemplate(); + + final HttpEntity httpEntity = new HttpEntity<>(getHeader()); + + final ResponseEntity response = restTemplate.exchange( + "http://localhost:8080/sm-shop/services/rest/products/DEFAULT/en/" + testCategoryID, HttpMethod.GET, + httpEntity, ReadableProduct[].class); + + if (response.getStatusCode() != HttpStatus.OK) { + throw new Exception(); + } else { + System.out.println(response.getBody().length + " Product records found."); + } + } + + @Test + @Ignore + public void putProduct() throws Exception { + restTemplate = new RestTemplate(); + + // TODO: Put Product + + } + + @Test + @Ignore + public void postProduct() throws Exception { + restTemplate = new RestTemplate(); + + final String code = "abcdef"; + + final PersistableProduct product = super.product(code); + + + + final String categoryCode = "ROOT";// root category + + final Category category = new Category(); + category.setCode(categoryCode); + final List categories = new ArrayList<>(); + categories.add(category); + + final String manufacturer = "temple"; + final Manufacturer collection = new Manufacturer(); + collection.setCode(manufacturer); + + // core properties + + + // product.setManufacturer(collection); //no manufacturer assigned for + // now + // product.setCategories(categories); //no category assigned for now + + product.setSortOrder(0);// set iterator as sort order + product.setAvailable(true);// force availability + product.setProductVirtual(false);// force tangible good + product.setQuantityOrderMinimum(1);// force to 1 minimum when ordering + product.setProductShipeable(true);// all items are shipeable + + /** images **/ + final String image = "/Users/carlsamson/Documents/csti/IMG_4626.jpg"; + // String image = "C:/personal/em/pictures-misc/IMG_2675.JPG"; + + final File imgPath = new File(image); + + // PersistableImage persistableImage = new PersistableImage(); + + // persistableImage.setBytes(this.extractBytes(imgPath)); + // persistableImage.setImageName(imgPath.getName()); + + // List images = new ArrayList(); + // images.add(persistableImage); + + // product.setImages(images); + + ProductSpecification specifications = new ProductSpecification(); + specifications.setHeight(new BigDecimal(20)); + specifications.setLength(new BigDecimal(21)); + specifications.setWeight(new BigDecimal(22)); + specifications.setWidth(new BigDecimal(23)); + + product.setProductSpecifications(specifications); + + + PersistableProductInventory inventory = new PersistableProductInventory(); + inventory.setQuantity(5); + inventory.setSku(code); + + + + final PersistableProductPrice productPrice = new PersistableProductPrice(); + productPrice.setDefaultPrice(true); + + productPrice.setPrice(new BigDecimal(250)); + productPrice.setDiscountedPrice(new BigDecimal(125)); + + final List productPriceList = new ArrayList<>(); + productPriceList.add(productPrice); + + inventory.setPrice(productPrice); + product.setInventory(inventory); + + final List descriptions = new ArrayList<>(); + + // add english description + ProductDescription description = new ProductDescription(); + description.setLanguage("en"); + description.setTitle("Statue Head"); + description.setName("Statue Head"); + description.setDescription("Statue Head"); + description.setFriendlyUrl("Statue-head"); + + descriptions.add(description); + + // add french description + description = new ProductDescription(); + description.setLanguage("fr"); + description.setTitle("Tête de Statue"); + description.setName("Tête de Statue"); + description.setDescription(description.getName()); + description.setFriendlyUrl("tete-de-Statue"); + // + + descriptions.add(description); + + product.setDescriptions(descriptions); + + final ObjectWriter writer = new ObjectMapper().writer().withDefaultPrettyPrinter(); + final String json = writer.writeValueAsString(product); + + System.out.println(json); + + final HttpEntity entity = new HttpEntity<>(json, getHeader()); + + // post to create category web service + final ResponseEntity response = restTemplate.postForEntity("http://localhost:8080/api/v1/product", entity, + PersistableProduct.class); + + final PersistableProduct prod = (PersistableProduct) response.getBody(); + + System.out.println("---------------------"); + + } + + @Test + @Ignore + public void deleteProduct() throws Exception { + restTemplate = new RestTemplate(); + + final HttpEntity httpEntity = new HttpEntity<>(getHeader()); + + restTemplate.exchange("http://localhost:8080/sm-shop/services/rest/product/DEFAULT/en/" + testCategoryID + "/" + + testProductID, HttpMethod.DELETE, httpEntity, ReadableProduct.class); + System.out.println("Product " + testProductID + " Deleted."); + } + + /** private helper methods **/ + public byte[] extractBytes(final File imgPath) throws Exception { + + final FileInputStream fis = new FileInputStream(imgPath); + + final BufferedInputStream inputStream = new BufferedInputStream(fis); + final byte[] fileBytes = new byte[(int) imgPath.length()]; + inputStream.read(fileBytes); + inputStream.close(); + + return fileBytes; + + } + +} \ No newline at end of file diff --git a/sm-shop/src/test/java/com/salesmanager/test/shop/integration/product/ProductV2ManagementAPIIntegrationTest.java b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/product/ProductV2ManagementAPIIntegrationTest.java new file mode 100644 index 0000000000..d6b2282c3c --- /dev/null +++ b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/product/ProductV2ManagementAPIIntegrationTest.java @@ -0,0 +1,146 @@ +package com.salesmanager.test.shop.integration.product; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.springframework.http.HttpStatus.CREATED; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.http.HttpEntity; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.shop.application.ShopApplication; +import com.salesmanager.shop.model.catalog.category.Category; +import com.salesmanager.shop.model.catalog.category.CategoryDescription; +import com.salesmanager.shop.model.catalog.category.PersistableCategory; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductOption; +import com.salesmanager.shop.model.catalog.product.attribute.PersistableProductOptionValue; +import com.salesmanager.shop.model.catalog.product.attribute.ProductOptionDescription; +import com.salesmanager.shop.model.catalog.product.attribute.ProductOptionValueDescription; +import com.salesmanager.shop.model.catalog.product.product.PersistableProduct; +import com.salesmanager.shop.model.catalog.product.product.ProductSpecification; +import com.salesmanager.shop.model.catalog.product.variation.PersistableProductVariation; +import com.salesmanager.test.shop.common.ServicesTestSupport; + + +@SpringBootTest(classes = ShopApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) +@RunWith(SpringRunner.class) +public class ProductV2ManagementAPIIntegrationTest extends ServicesTestSupport { + + + @Test + public void createProductWithCategory() throws Exception { + + + /** + * Create a category for product association + */ + final PersistableCategory newCategory = new PersistableCategory(); + newCategory.setCode("test-catv2"); + newCategory.setSortOrder(1); + newCategory.setVisible(true); + newCategory.setDepth(4); + + final Category parent = new Category(); + + newCategory.setParent(parent); + + final CategoryDescription description = new CategoryDescription(); + description.setLanguage("en"); + description.setName("test-catv2"); + description.setFriendlyUrl("test-catv2"); + description.setTitle("test-catv2"); + + final List descriptions = new ArrayList<>(); + descriptions.add(description); + + newCategory.setDescriptions(descriptions); + + final HttpEntity categoryEntity = new HttpEntity<>(newCategory, getHeader()); + + final ResponseEntity categoryResponse = testRestTemplate.postForEntity( + "/api/v1/private/category?store=" + Constants.DEFAULT_STORE, categoryEntity, PersistableCategory.class); + final PersistableCategory cat = categoryResponse.getBody(); + assertTrue(categoryResponse.getStatusCode()== CREATED); + assertNotNull(cat.getId()); + + final PersistableProduct product = super.product("123"); + final ArrayList categories = new ArrayList<>(); + categories.add(cat); + product.setCategories(categories); + ProductSpecification specifications = new ProductSpecification(); + specifications.setManufacturer( + com.salesmanager.core.model.catalog.product.manufacturer.Manufacturer.DEFAULT_MANUFACTURER); + product.setProductSpecifications(specifications); + product.setPrice(BigDecimal.TEN); + + final HttpEntity productEntity = new HttpEntity<>(product, getHeader()); + final ResponseEntity response = testRestTemplate.postForEntity( + "/api/v2/private/product?store=" + Constants.DEFAULT_STORE, productEntity, PersistableProduct.class); + assertTrue(response.getStatusCode()== CREATED); + + //create options + PersistableProductOption color = new PersistableProductOption(); + color.setCode("color"); + ProductOptionDescription colorEn = new ProductOptionDescription(); + colorEn.setName("Color"); + colorEn.setLanguage("en"); + color.getDescriptions().add(colorEn); + + final HttpEntity colorEntity = new HttpEntity<>(color, getHeader()); + final ResponseEntity colorResponse = testRestTemplate.postForEntity( + "/api/v1/private/product/option?store=" + Constants.DEFAULT_STORE, colorEntity, PersistableProductOption.class); + assertTrue(colorResponse.getStatusCode()== CREATED); + System.out.println(colorResponse.getBody().getId()); + + + PersistableProductOption size = new PersistableProductOption(); + size.setCode("size"); + ProductOptionDescription sizeEn = new ProductOptionDescription(); + sizeEn.setName("Size"); + sizeEn.setLanguage("en"); + size.getDescriptions().add(sizeEn); + + final HttpEntity sizeEntity = new HttpEntity<>(size, getHeader()); + final ResponseEntity sizeResponse = testRestTemplate.postForEntity( + "/api/v1/private/product/option?store=" + Constants.DEFAULT_STORE, sizeEntity, PersistableProductOption.class); + assertTrue(sizeResponse.getStatusCode()== CREATED); + System.out.println(colorResponse.getBody().getId()); + + //opions values + PersistableProductOptionValue white = new PersistableProductOptionValue(); + white.setCode("white"); + ProductOptionValueDescription whiteEn = new ProductOptionValueDescription(); + whiteEn.setName("White"); + whiteEn.setLanguage("en"); + white.getDescriptions().add(whiteEn); + + final HttpEntity whiteEntity = new HttpEntity<>(white, getHeader()); + final ResponseEntity whiteResponse = testRestTemplate.postForEntity( + "/api/v1/private/product/option?store=" + Constants.DEFAULT_STORE, whiteEntity, PersistableProductOptionValue.class); + assertTrue(whiteResponse.getStatusCode()== CREATED); + System.out.println(whiteResponse.getBody().getId()); + + PersistableProductOptionValue medium = new PersistableProductOptionValue(); + medium.setCode("medium"); + ProductOptionValueDescription mediumEn = new ProductOptionValueDescription(); + mediumEn.setName("Medium"); + mediumEn.setLanguage("en"); + white.getDescriptions().add(mediumEn); + + //create variantions + PersistableProductVariation whiteVariation = new PersistableProductVariation(); + PersistableProductVariation mediumVariation = new PersistableProductVariation(); + // toto + //create variants + } + +} diff --git a/sm-shop/src/test/java/com/salesmanager/test/shop/integration/search/SearchApiIntegrationTest.java b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/search/SearchApiIntegrationTest.java new file mode 100755 index 0000000000..38eed06c3c --- /dev/null +++ b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/search/SearchApiIntegrationTest.java @@ -0,0 +1,63 @@ +package com.salesmanager.test.shop.integration.search; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; +import static org.springframework.http.HttpStatus.CREATED; + +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +import com.salesmanager.core.business.constants.Constants; +import com.salesmanager.shop.application.ShopApplication; +import com.salesmanager.shop.model.catalog.SearchProductList; +import com.salesmanager.shop.model.catalog.SearchProductRequest; +import com.salesmanager.shop.model.catalog.product.product.PersistableProduct; +import com.salesmanager.test.shop.common.ServicesTestSupport; + +@SpringBootTest(classes = ShopApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) +@RunWith(SpringRunner.class) +@Ignore +public class SearchApiIntegrationTest extends ServicesTestSupport { + + @Autowired + private TestRestTemplate testRestTemplate; + + + + /** + * Add a product then search for it + * This tests is disabled since it requires Elastic search server started + * + * @throws Exception + */ + //@Test + @Ignore + public void searchItem() throws Exception { + + PersistableProduct product = super.product("TESTPRODUCT"); + + final HttpEntity entity = new HttpEntity<>(product, getHeader()); + + final ResponseEntity response = testRestTemplate.postForEntity("/api/v1/private/product?store=" + Constants.DEFAULT_STORE, entity, PersistableProduct.class); + assertThat(response.getStatusCode(), is(CREATED)); + + SearchProductRequest searchRequest = new SearchProductRequest(); + searchRequest.setQuery("TEST"); + final HttpEntity searchEntity = new HttpEntity<>(searchRequest, getHeader()); + + + final ResponseEntity searchResponse = testRestTemplate.postForEntity("/api/v1/search?store=" + Constants.DEFAULT_STORE, searchEntity, SearchProductList.class); + assertThat(searchResponse.getStatusCode(), is(CREATED)); + + } + + +} \ No newline at end of file diff --git a/sm-shop/src/test/java/com/salesmanager/test/shop/integration/store/MerchantStoreApiIntegrationTest.java b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/store/MerchantStoreApiIntegrationTest.java new file mode 100755 index 0000000000..a3a9868634 --- /dev/null +++ b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/store/MerchantStoreApiIntegrationTest.java @@ -0,0 +1,118 @@ +package com.salesmanager.test.shop.integration.store; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertNotNull; +import java.util.Arrays; +import javax.inject.Inject; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.util.LinkedMultiValueMap; +import com.salesmanager.core.model.merchant.MerchantStore; +import com.salesmanager.shop.application.ShopApplication; +import com.salesmanager.shop.model.references.PersistableAddress; +import com.salesmanager.shop.model.store.PersistableMerchantStore; +import com.salesmanager.shop.model.store.ReadableMerchantStore; +import com.salesmanager.test.shop.common.ServicesTestSupport; + +@SpringBootTest(classes = ShopApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) +@RunWith(SpringRunner.class) +public class MerchantStoreApiIntegrationTest extends ServicesTestSupport { + + private static final String TEST_STORE_CODE = "test"; + private static final String CURRENCY = "CAD"; + private static final String DEFAULT_LANGUAGE = "en"; + + @Inject + private TestRestTemplate testRestTemplate; + + /** + * Test get DEFAULT store + * @throws Exception + */ + @Test + public void testGetDefaultStore() throws Exception { + final HttpEntity httpEntity = new HttpEntity<>(getHeader()); + + final ResponseEntity response = testRestTemplate.exchange(String.format("/api/v1/store/" + MerchantStore.DEFAULT_STORE), HttpMethod.GET, + httpEntity, ReadableMerchantStore.class); + if (response.getStatusCode() != HttpStatus.OK) { + throw new Exception(response.toString()); + } else { + final ReadableMerchantStore store = response.getBody(); + assertNotNull(store); + } + } + + /** + * Create a new store then delete it + * @throws Exception + */ + @Test + public void testCreateStore() throws Exception { + + + PersistableAddress address = new PersistableAddress(); + address.setAddress("121212 simple address"); + address.setPostalCode("12345"); + address.setCountry("US"); + address.setCity("FT LD"); + address.setStateProvince("FL"); + + PersistableMerchantStore createdStore = new PersistableMerchantStore(); + createdStore.setCode(TEST_STORE_CODE); + createdStore.setCurrency(CURRENCY); + createdStore.setDefaultLanguage(DEFAULT_LANGUAGE); + createdStore.setEmail("test@test.com"); + createdStore.setName(TEST_STORE_CODE); + createdStore.setPhone("444-555-6666"); + createdStore.setSupportedLanguages(Arrays.asList(DEFAULT_LANGUAGE)); + createdStore.setAddress(address); + + final HttpEntity httpEntity = new HttpEntity(createdStore, getHeader()); + + ResponseEntity response = testRestTemplate.exchange(String.format("/api/v1/private/store/"), HttpMethod.POST, httpEntity, Void.class); + + assertThat(response.getStatusCode(), is(HttpStatus.OK)); + + } + + + @Test + public void testAddAndDeleteStoreLogo() { + LinkedMultiValueMap parameters = new LinkedMultiValueMap(); + parameters.add("file", new org.springframework.core.io.ClassPathResource("image.jpg")); + + HttpHeaders headers = getHeader(); + headers.setContentType(MediaType.MULTIPART_FORM_DATA); + + HttpEntity> entity = new HttpEntity>(parameters, headers); + + ResponseEntity createResponse = testRestTemplate.exchange(String.format("/api/v1/private/store/" + MerchantStore.DEFAULT_STORE + "/marketing/logo"), HttpMethod.POST, entity, Void.class); + + // Expect Created + assertThat(createResponse.getStatusCode(), is(HttpStatus.CREATED)); + + // now remove logo + HttpEntity deleteRequest = new HttpEntity(getHeader()); + + ResponseEntity deleteResponse = testRestTemplate.exchange(String.format("/api/v1/private/store/" + MerchantStore.DEFAULT_STORE + "/marketing/logo"), HttpMethod.DELETE, deleteRequest, Void.class); + + // Expect Ok + assertThat(deleteResponse.getStatusCode(), is(HttpStatus.OK)); + + } + + + +} diff --git a/sm-shop/src/test/java/com/salesmanager/test/shop/integration/system/ActuatorTest.java b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/system/ActuatorTest.java new file mode 100644 index 0000000000..4cfa22ad66 --- /dev/null +++ b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/system/ActuatorTest.java @@ -0,0 +1,44 @@ +package com.salesmanager.test.shop.integration.system; + +import javax.inject.Inject; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +import com.salesmanager.shop.application.ShopApplication; + + + +@SpringBootTest(classes = ShopApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) +@RunWith(SpringRunner.class) +public class ActuatorTest { + + @Inject + private TestRestTemplate testRestTemplate; + + + @Test + public void testPing() throws Exception { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + HttpEntity entity = new HttpEntity(headers); + + final ResponseEntity response = testRestTemplate. + exchange("/actuator/health/ping/", HttpMethod.GET, entity, Void.class); + if (response.getStatusCode() != HttpStatus.OK) { + throw new Exception(response.toString()); + } + } + +} diff --git a/sm-shop/src/test/java/com/salesmanager/test/shop/integration/system/OptinApiIntegrationTest.java b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/system/OptinApiIntegrationTest.java new file mode 100755 index 0000000000..ef59404b15 --- /dev/null +++ b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/system/OptinApiIntegrationTest.java @@ -0,0 +1,76 @@ +package com.salesmanager.test.shop.integration.system; + +import static org.junit.Assert.assertTrue; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.salesmanager.core.model.system.optin.OptinType; +import com.salesmanager.shop.application.ShopApplication; +import com.salesmanager.shop.model.customer.optin.PersistableCustomerOptin; +import com.salesmanager.shop.model.system.PersistableOptin; +import com.salesmanager.test.shop.common.ServicesTestSupport; + +@SpringBootTest(classes = ShopApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) +@RunWith(SpringRunner.class) +public class OptinApiIntegrationTest extends ServicesTestSupport { + + @Autowired + private TestRestTemplate testRestTemplate; + + + @Test + public void createOptin() throws Exception { + + PersistableOptin optin = new PersistableOptin(); + optin.setCode(OptinType.PROMOTIONS.name()); + optin.setOptinType(OptinType.PROMOTIONS.name()); + + + final ObjectWriter writer = new ObjectMapper().writer().withDefaultPrettyPrinter(); + final String json = writer.writeValueAsString(optin); + + + final HttpEntity entity = new HttpEntity<>(json, getHeader()); + final ResponseEntity response = testRestTemplate.postForEntity("/api/v1/private/optin", entity, PersistableOptin.class); + + if (response.getStatusCode() != HttpStatus.OK) { + throw new Exception(response.toString()); + } else { + assertTrue(true); + } + } + + public void createCustomerOptinNewsletter() throws Exception { + + + PersistableCustomerOptin customerOptin = new PersistableCustomerOptin(); + customerOptin.setEmail("test@test.com"); + customerOptin.setFirstName("Jack"); + customerOptin.setLastName("John"); + + final ObjectWriter writer = new ObjectMapper().writer().withDefaultPrettyPrinter(); + final String json = writer.writeValueAsString(customerOptin); + System.out.println(json); + + final HttpEntity e = new HttpEntity<>(json); + final ResponseEntity resp = testRestTemplate.postForEntity("/api/v1/newsletter", e, PersistableCustomerOptin.class); + + if (resp.getStatusCode() != HttpStatus.OK) { + throw new Exception(resp.toString()); + } else { + assertTrue(true); + } + + +} + +} diff --git a/sm-shop/src/test/java/com/salesmanager/test/shop/integration/tax/TaxRateIntegrationTest.java b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/tax/TaxRateIntegrationTest.java new file mode 100644 index 0000000000..70ba50cdc7 --- /dev/null +++ b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/tax/TaxRateIntegrationTest.java @@ -0,0 +1,116 @@ +package com.salesmanager.test.shop.integration.tax; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.math.BigDecimal; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +import com.salesmanager.shop.application.ShopApplication; +import com.salesmanager.shop.model.entity.Entity; +import com.salesmanager.shop.model.entity.EntityExists; +import com.salesmanager.shop.model.tax.PersistableTaxClass; +import com.salesmanager.shop.model.tax.PersistableTaxRate; +import com.salesmanager.shop.model.tax.TaxRateDescription; +import com.salesmanager.test.shop.common.ServicesTestSupport; + +@SpringBootTest(classes = ShopApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) +@RunWith(SpringRunner.class) +public class TaxRateIntegrationTest extends ServicesTestSupport { + + + @Test + public void manageTaxClass() throws Exception { + + //create tax class + PersistableTaxClass taxClass = new PersistableTaxClass(); + taxClass.setCode("TESTTX"); + taxClass.setName("Test tax class"); + + final HttpEntity taxClassEntity = new HttpEntity<>(taxClass, getHeader()); + final ResponseEntity response = testRestTemplate.postForEntity(String.format("/api/v1/private/tax/class/"), taxClassEntity, Entity.class); + + Entity e = response.getBody(); + + assertNotNull(e.getId()); + assertTrue(e.getId() > 0); + + + final HttpEntity httpEntity = new HttpEntity<>(getHeader()); + + //tax class exists + final ResponseEntity exists = testRestTemplate.exchange(String.format("/api/v1/private/tax/class/unique?code=" + taxClass.getCode()), HttpMethod.GET, + httpEntity, EntityExists.class); + + assertTrue(exists.getBody().isExists()); + + + /** + //list 1 taxClass + @SuppressWarnings("rawtypes") + final ResponseEntity listOfTaxClasses = testRestTemplate.exchange(String.format("/private/tax/class"), HttpMethod.GET, + httpEntity, ReadableEntityList.class); + + assertTrue(listOfTaxClasses.getBody().getRecordsTotal() == 1); + **/ + + } + + @Test + public void manageTaxRates() throws Exception { + + //create tax class + PersistableTaxRate taxRate = new PersistableTaxRate(); + taxRate.setCode("taxcode1"); + taxRate.setCountry("US"); + taxRate.setPriority(0); + taxRate.setRate(new BigDecimal(5)); + taxRate.setStore("DEFAULT"); + taxRate.setTaxClass("DEFAULT"); + taxRate.setZone("NY"); + + //descriptions + TaxRateDescription en = new TaxRateDescription(); + en.setLanguage("en"); + en.setName("TaxCode1EN"); + en.setDescription("TaxCode1EN description"); + + TaxRateDescription fr = new TaxRateDescription(); + fr.setLanguage("fr"); + fr.setName("TaxCode1FR"); + fr.setDescription("TaxCode1fr description"); + + taxRate.getDescriptions().add(en); + taxRate.getDescriptions().add(fr); + + + final HttpEntity taxClassEntity = new HttpEntity<>(taxRate, getHeader()); + final ResponseEntity response = testRestTemplate.postForEntity(String.format("/api/v1/private/tax/rate/"), taxClassEntity, Entity.class); + + Entity e = response.getBody(); + + assertNotNull(e.getId()); + assertTrue(e.getId() > 0); + + + final HttpEntity httpEntity = new HttpEntity<>(getHeader()); + + //tax class exists + final ResponseEntity exists = testRestTemplate.exchange(String.format("/api/v1/private/tax/rate/unique?code=" + taxRate.getCode()), HttpMethod.GET, + httpEntity, EntityExists.class); + + assertTrue(exists.getBody().isExists()); + + + + } + +} diff --git a/sm-shop/src/test/java/com/salesmanager/test/shop/integration/user/UserApiIntegrationTest.java b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/user/UserApiIntegrationTest.java new file mode 100755 index 0000000000..47ccb8fc50 --- /dev/null +++ b/sm-shop/src/test/java/com/salesmanager/test/shop/integration/user/UserApiIntegrationTest.java @@ -0,0 +1,99 @@ +package com.salesmanager.test.shop.integration.user; + +import static org.junit.Assert.assertNotNull; +import javax.inject.Inject; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; +import com.salesmanager.shop.application.ShopApplication; +import com.salesmanager.shop.model.security.PersistableGroup; +import com.salesmanager.shop.model.user.PersistableUser; +import com.salesmanager.shop.model.user.ReadableUser; +import com.salesmanager.shop.model.user.UserPassword; +import com.salesmanager.test.shop.common.ServicesTestSupport; + +@SpringBootTest(classes = ShopApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) +@RunWith(SpringRunner.class) +public class UserApiIntegrationTest extends ServicesTestSupport { + + private static Long DEFAULT_USER_ID = 1L; + private static String CREATED_PASSWORD = "Password1"; + private static String NEW_CREATED_PASSWORD = "Password2"; + + @Inject + private TestRestTemplate testRestTemplate; + + @Test + public void getUser() throws Exception { + final HttpEntity httpEntity = new HttpEntity<>(getHeader()); + + final ResponseEntity response = testRestTemplate.exchange(String.format("/api/v1/private/users/" + DEFAULT_USER_ID), HttpMethod.GET, + httpEntity, ReadableUser.class); + if (response.getStatusCode() != HttpStatus.OK) { + throw new Exception(response.toString()); + } else { + final ReadableUser user = response.getBody(); + assertNotNull(user); + } + } + + @Test + public void createUserChangePassword() throws Exception { + + PersistableUser newUser = new PersistableUser(); + newUser.setDefaultLanguage("en"); + newUser.setEmailAddress("test@test.com"); + newUser.setFirstName("Test"); + newUser.setLastName("User"); + newUser.setUserName("test@test.com"); + newUser.setPassword(CREATED_PASSWORD); + newUser.setRepeatPassword(CREATED_PASSWORD); + + PersistableGroup g = new PersistableGroup(); + g.setName("ADMIN"); + + newUser.getGroups().add(g); + + final HttpEntity persistableUser = new HttpEntity(newUser, getHeader()); + + ReadableUser user = null; + final ResponseEntity response = testRestTemplate.exchange(String.format("/api/v1/private/user/"), HttpMethod.POST, + persistableUser, ReadableUser.class); + if (response.getStatusCode() != HttpStatus.OK) { + throw new Exception(response.toString()); + } else { + user = response.getBody(); + assertNotNull(user); + } + + String oldPassword = CREATED_PASSWORD; + String newPassword = NEW_CREATED_PASSWORD; + String repeatPassword = newPassword; + + UserPassword userPassword = new UserPassword(); + userPassword.setPassword(oldPassword); + userPassword.setChangePassword(newPassword); + + final HttpEntity changePasswordEntity = new HttpEntity(userPassword, getHeader()); + + + final ResponseEntity changePassword = testRestTemplate.exchange(String.format("/api/v1/private/user/" + user.getId() + "/password"), HttpMethod.PATCH, changePasswordEntity, Void.class); + if (changePassword.getStatusCode() != HttpStatus.OK) { + throw new Exception(response.toString()); + } else { + assertNotNull("Password changed"); + } + + + } + + + +} diff --git a/sm-shop/src/test/java/com/salesmanager/test/shop/util/GeneratePasswordTest.java b/sm-shop/src/test/java/com/salesmanager/test/shop/util/GeneratePasswordTest.java new file mode 100755 index 0000000000..938b978b50 --- /dev/null +++ b/sm-shop/src/test/java/com/salesmanager/test/shop/util/GeneratePasswordTest.java @@ -0,0 +1,49 @@ +package com.salesmanager.test.shop.util; + +import javax.inject.Inject; +import javax.inject.Named; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.test.context.junit4.SpringRunner; + +import com.salesmanager.shop.application.ShopApplication; +import com.salesmanager.test.shop.common.ServicesTestSupport; + + +/** + * This utility is for password encryption + * @author carlsamson + * + */ +@SpringBootTest(classes = ShopApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) +@RunWith(SpringRunner.class) +public class GeneratePasswordTest extends ServicesTestSupport { + + private static final Logger LOGGER = LoggerFactory.getLogger(GeneratePasswordTest.class); + + @Inject + @Named("passwordEncoder") + private PasswordEncoder passwordEncoder; + + @Test + public void createPassword() throws Exception { + + + String password ="password"; + String encoded = passwordEncoder.encode(password); + LOGGER.info(encoded); + System.out.println(encoded); + //To comply with sonarlint rule java:S2699 + Assert.assertNotNull(encoded); + } + + + +} diff --git a/sm-shop/src/test/resources/application-test.properties b/sm-shop/src/test/resources/application-test.properties new file mode 100755 index 0000000000..ee091f0fa7 --- /dev/null +++ b/sm-shop/src/test/resources/application-test.properties @@ -0,0 +1,51 @@ +#Spring boot configurations +#logging.config=log4j-shopizer.properties +server.port=8080 + + +#Turn Statistics on +#spring.jpa.properties.hibernate.generate_statistics=true +#default database schema +spring.jpa.properties.hibernate.default_schema=SALESMANAGER +#logging.level.org.hibernate.stat=debug + +# Enable logging to verify that HikariCP is used, the second entry is specific to HikariCP +#INFO | DEBUG +logging.level.org.hibernate.SQL=DEBUG +logging.level.com.zaxxer.hikari.HikariConfig=INFO +logging.level.org.hibernate.type.descriptor.sql.BasicBinder=DEBUG + +#when running from IDE (eclipse) or from springboot:run command +#server.contextPath=/shopizer + +logging.level.org.springframework=INFO +logging.level.com.shopizer=INFO +logging.level.org.hibernate=INFO +logging.level.org.apache.http=ERROR + +#logging.file=shopizer.log + +#Default Spring white label error page +server.error.whitelabel.enabled=false + +spring.servlet.multipart.max-file-size=4MB +spring.servlet.multipart.max-request-size=10MB + + +#hibernate 5 +#spring.jpa.hibernate.use-new-id-generator-mappings=true + +#Spring boot 2.X +spring.main.allow-bean-definition-overriding=true + +#actuator +management.endpoints.enabled-by-default=false +management.endpoint.info.enabled=true +management.endpoint.health.enabled=true +management.endpoint.health.sensitive=false +management.endpoint.health.show-details=always + +management.health.probes.enabled=true + +management.endpoint.health.group.global.include=ping +management.security.enabled=false \ No newline at end of file diff --git a/sm-shop/src/test/resources/database.properties b/sm-shop/src/test/resources/database.properties new file mode 100755 index 0000000000..1b4b8a504c --- /dev/null +++ b/sm-shop/src/test/resources/database.properties @@ -0,0 +1,41 @@ +## +## db config +## + +#Need to run these commands before running shopizer - choose your username and password +#mysql>CREATE DATABASE SALESMANAGER; +#mysql>CREATE USER shopizer IDENTIFIED BY 'very-long-shopizer-password'; +#mysql>GRANT ALL ON SALESMANAGER.* TO shopizer; +#mysql>FLUSH PRIVILEGES; + + +#MYSQL +#db.jdbcUrl=jdbc:mysql://127.0.0.1:3306/SALESMANAGER?#autoReconnect=true&useUnicode=true&characterEncoding=UTF-8 +#db.user=root +#db.password=password +#db.driverClass=com.mysql.jdbc.Driver +#hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect + + +#for using file database +#db.jdbcUrl=jdbc\:h2\:file\:./SALESMANAGER-TEST;AUTOCOMMIT=OFF;;mv_store=false;INIT\=CREATE SCHEMA IF NOT EXISTS SALESMANAGER +#for using memory database +db.jdbcUrl=jdbc\:h2\:mem\:SALESMANAGER-TEST;AUTOCOMMIT=OFF;;mv_store=false;INIT\=CREATE SCHEMA IF NOT EXISTS SALESMANAGER +db.user=test +db.password=password +db.driverClass=org.h2.Driver +hibernate.dialect=org.hibernate.dialect.H2Dialect + +db.show.sql=false +db.preferredTestQuery=SELECT 1 +db.schema=SALESMANAGER +hibernate.hbm2ddl.auto=create + + + +## +## configuration pooling base de donn\uFFFDes +## +db.initialPoolSize=4 +db.minPoolSize=4 +db.maxPoolSize=8 \ No newline at end of file diff --git a/sm-shop/src/test/resources/image.jpg b/sm-shop/src/test/resources/image.jpg new file mode 100755 index 0000000000..6eb533263c Binary files /dev/null and b/sm-shop/src/test/resources/image.jpg differ diff --git a/sm-shop/src/test/resources/log4j.properties b/sm-shop/src/test/resources/log4j.properties new file mode 100755 index 0000000000..38d6d36cff --- /dev/null +++ b/sm-shop/src/test/resources/log4j.properties @@ -0,0 +1,14 @@ +log4j.appender.Stdout=org.apache.log4j.ConsoleAppender +log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.Stdout.layout.ConversionPattern=[%d{ISO8601}] %-5p - %-26.26c{1} - %m\n + +log4j.rootLogger=WARN,Stdout + +# hibernate queries +log4j.logger.org.hibernate.SQL=DEBUG +log4j.logger.org.hibernate.type=INFO + +# schema initialization +log4j.logger.org.hibernate.tool.hbm2ddl=DEBUG + +log4j.logger.org.springframework.transaction=DEBUG diff --git a/sm-shop/src/test/resources/log4j.xml b/sm-shop/src/test/resources/log4j.xml new file mode 100755 index 0000000000..1f1a0ff703 --- /dev/null +++ b/sm-shop/src/test/resources/log4j.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +