diff --git a/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/README.md b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/README.md index 91acd093..de14b8ba 100644 --- a/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/README.md +++ b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/README.md @@ -1,10 +1,8 @@ # Implementing a Custom Order Validator -This tutorial will show you how to add ... by implementing the `Foo` interface. +This tutorial will show you how to add a custom order validator by implementing the `CommerceOrderValidator` interface. -Liferay Commerce provides ... - -(Establishing Image Placeholder) +An order validator is a class that validates items in a customer's cart when proceeding through checkout. Liferay Commerce provides multiple out of the box order validators, including a [default](https://raw.githubusercontent.com/liferay/com-liferay-commerce/7.1.x/commerce-service/src/main/java/com/liferay/commerce/internal/order/DefaultCommerceOrderValidatorImpl.java), as well as validators to check [item versions](https://raw.githubusercontent.com/liferay/com-liferay-commerce/7.1.x/commerce-service/src/main/java/com/liferay/commerce/internal/order/VersionCommerceOrderValidatorImpl.java) and [recurring items (subscriptions)](https://raw.githubusercontent.com/liferay/com-liferay-commerce/7.1.x/commerce-service/src/main/java/com/liferay/commerce/internal/order/SubscriptionCommerceOrderValidatorImpl.java). ## Overview @@ -14,7 +12,7 @@ Liferay Commerce provides ... ## Deploy an Example -In this section, we will get an example ... up and running on your instance of Liferay Commerce. Follow these steps: +In this section, we will get an example order validator up and running on your instance of Liferay Commerce. Follow these steps: 1. Start Liferay Commerce. @@ -22,20 +20,20 @@ In this section, we will get an example ... up and running on your instance of L docker run -it -p 8080:8080 liferay/commerce:2.0.2 ``` -1. Download and unzip the [Acme Commerce ...]() to your project directory. +1. Download and unzip the [Acme Commerce Order Validator]() to your project directory. ```bash - curl liferay-xxxx.zip + curl liferay-n9b2.zip ``` ```bash - unzip liferay-xxxx.zip + unzip liferay-n9b2.zip ``` -1. Go to `xxxx-impl`. +1. Go to `n9b2-impl`. ```bash - cd xxxx-impl + cd n9b2-impl ``` 1. Build and deploy the example. @@ -44,32 +42,185 @@ In this section, we will get an example ... up and running on your instance of L ./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq) ``` - >Note: This command is the same as copying the deployed jars to /opt/liferay/osgi/modules on the Docker container. + > Note: This command is the same as copying the deployed jars to /opt/liferay/osgi/modules on the Docker container. 1. Confirm the deployment in the Liferay Docker container console. ```bash - STARTED com.acme.xxxx.internal.commerce.foo.method_1.0.0 + STARTED com.acme.n9b2.internal.commerce.order.validator_1.0.0 ``` -1. Verify that the example ... was added. Open your browser to `https://localhost:8080` and navigate to ... +1. Verify that the example order validator was added by viewing the failure message. Open your browser to `https://localhost:8080` and navigate to a catalog with at least one item priced over $100. If one does not exist, you may need to add it yourself; see [Products](https://commerce.liferay.dev/user-guide/-/knowledge_base/user/products) for more information on this. + + Once in the catalog, search for the item with this price, then click "Add to Cart". Increase the quantity to 11 or more, then click the arrow to continue. The error message that appears shows that the custom order validator successfully rejected adding the item. -(Deployed Sample Image Placeholder) +![New order validation error message](./images/01.png "New order validation error message") Next, let's dive deeper to learn more. ## Walk Through the Example -In this section, we will take a more in-depth review of the example we deployed. First, we will annotate the class for OSGi registration; second we will implement the `Foo` interface; and third, we will implement the ... logic. +In this section, we will take a more in-depth review of the example we deployed. First, we will annotate the class for OSGi registration; second we will implement the `CommerceOrderValidator` interface; and third, we will implement the custom validation logic. ### Annotate Your Class for OSGi Registration -### Implement the `Foo` Interface +```java +@Component( + immediate = true, + property = { + "commerce.order.validator.key=" + N9B2CommerceOrderValidator.KEY, + "commerce.order.validator.priority:Integer=9" + }, + service = CommerceOrderValidator.class +) +public class N9B2CommerceOrderValidator implements CommerceOrderValidator { + + public static final String KEY = "example"; +``` + +> It is important to provide a distinct key for your order validator so that Liferay Commerce can distinguish your new order validator from others in the [order validator registry](https://github.com/liferay/com-liferay-commerce/blob/7.1.x/commerce-service/src/main/java/com/liferay/commerce/internal/order/CommerceOrderValidatorRegistryImpl.java). Reusing a key that is already in use will override the existing associated validator. + +### Implement the `CommerceOrderValidator` Interface + +The following three methods are required: + +```java +public String getKey(); +``` + +```java +public CommerceOrderValidatorResult validate(Locale locale, CommerceOrder commerceOrder, CPInstance cpInstance, int quantity) throws PortalException; +``` + +```java +public CommerceOrderValidatorResult validate(Locale locale, CommerceOrderItem commerceOrderItem) throws PortalException; +``` + +To better understand each of the required methods mentioned above, let's look at [N9B2CommerceOrderValidator.java](./liferay-n9b2.zip/n9b2-impl/src/main/java/com/acme/n9b2/internal/commerce/order/validator/N9B2CommerceOrderValidator.java). We will review the implementation of each required method in sequence. + +1. `public String getKey();` + + ```java + @Override + public String getKey() { + return KEY; + } + ``` + + > This method provides a unique identifier for the order validator in the registry. The key can be used to fetch the validator from the registry programmatically if necessary. Reusing a key that is already in use will override the existing associated validator. + +1. `public CommerceOrderValidatorResult validate(Locale locale, CommerceOrder commerceOrder, CPInstance cpInstance, int quantity) throws PortalException;` + + ```java + @Override + public CommerceOrderValidatorResult validate( + Locale locale, CommerceOrder commerceOrder, CPInstance cpInstance, + int quantity) + throws PortalException { + + if (cpInstance == null) { + return new CommerceOrderValidatorResult(false); + } + + return new CommerceOrderValidatorResult(true); + } + ``` + + > This is one of the two validation methods where we will add our custom validation logic. This method is called whenever a customer adds an item to their cart. It does this by returning a `CommerceOrderValidatorResult`, which uses a boolean to determine whether or not the result passes validation; see this class at [CommerceOrderValidatorResult.java](https://github.com/liferay/com-liferay-commerce/blob/7.1.x/commerce-api/src/main/java/com/liferay/commerce/order/CommerceOrderValidatorResult.java). + > + > Note that this dummy implementation only has a simple check for a null value, which is a standard first step for this method. + +1. `public CommerceOrderValidatorResult validate(Locale locale, CommerceOrderItem commerceOrderItem) throws PortalException;` + + ```java + @Override + public CommerceOrderValidatorResult validate( + Locale locale, CommerceOrderItem commerceOrderItem) + throws PortalException { + + return new CommerceOrderValidatorResult(true); + } + ``` + + > This is the second validation method where we can add custom validation logic. This method is called for items already in the cart, whenever a customer proceeds to a new step in checkout. + +### Create Your Validation Steps + +The two `validate()` methods are where we define the custom validation logic for our order validator. In our simple example, we will add logic to reject orders with more than ten of an item over a certain price. -### Create Your Method +1. `public CommerceOrderValidatorResult validate(Locale locale, CommerceOrder commerceOrder, CPInstance cpInstance, int quantity)` + + ```java + @Override + public CommerceOrderValidatorResult validate( + Locale locale, CommerceOrder commerceOrder, CPInstance cpInstance, + int quantity) + throws PortalException { + + if (cpInstance == null) { + return new CommerceOrderValidatorResult(false); + } + + BigDecimal price = cpInstance.getPrice(); + + if (price.doubleValue() > 100.0 && (quantity > 10)) { + ResourceBundle resourceBundle = ResourceBundleUtil.getBundle( + "content.Language", locale, getClass()); + + return new CommerceOrderValidatorResult( + false, LanguageUtil.get( + resourceBundle, "this-item-has-a-maximum-quantity-of-10")); + } + + return new CommerceOrderValidatorResult(true); + } + ``` + + > After a standard null check for this method, the main validation check for our example is to check if both the price (stored as a [BigDecimal](https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html)) is more than $100, and the quantity is greater than ten. We get the price information from the CPInstance, which contains information about the order the customer has added; to find more methods you can use with a `CPInstance`, see [CPInstance](https://raw.githubusercontent.com/liferay/com-liferay-commerce/7.1.x/commerce-product-api/src/main/java/com/liferay/commerce/product/model/CPInstance.java) and [CPInstanceModel](https://raw.githubusercontent.com/liferay/com-liferay-commerce/7.1.x/commerce-product-api/src/main/java/com/liferay/commerce/product/model/CPInstanceModel.java). + > + > Note that, for our main validation checks, it is best practice to include a localized message explaining why the validation failed. For this to work correctly using `LanguageUtil`, we will need to add the language key ourselves. For more information, see [Localizing Your Application](https://help.liferay.com/hc/en-us/articles/360018168251-Localizing-Your-Application). + +1. `public CommerceOrderValidatorResult validate(Locale locale, CommerceOrderItem commerceOrderItem)` + + ```java + @Override + public CommerceOrderValidatorResult validate( + Locale locale, CommerceOrderItem commerceOrderItem) + throws PortalException { + + BigDecimal price = commerceOrderItem.getUnitPrice(); + + if (price.doubleValue() > 100.0 && + commerceOrderItem.getQuantity() > 10) { + + ResourceBundle resourceBundle = ResourceBundleUtil.getBundle( + "content.Language", locale, getClass()); + + return new CommerceOrderValidatorResult( + false, LanguageUtil.get( + resourceBundle, + "expensive-items-have-a-maximum-quantity-of-10")); + } + + return new CommerceOrderValidatorResult(true); + } + ``` + + > We can add the same validation logic to this method, since it will be called for the items in the customer's cart. The main difference in this case is we get the information from a `CommerceOrderItem` object; to find more methods you can use with a `CommerceOrderItem`, see [CommerceOrderItem](https://raw.githubusercontent.com/liferay/com-liferay-commerce/7.1.x/commerce-api/src/main/java/com/liferay/commerce/model/CommerceOrderItem.java) and [CommerceOrderItemModel](https://raw.githubusercontent.com/liferay/com-liferay-commerce/7.1.x/commerce-api/src/main/java/com/liferay/commerce/model/CommerceOrderItemModel.java). + +We will also need to add the language keys for our validator's error messages. Add the keys and their values to a Language.properties file within our module: + +```java +expensive-items-have-a-maximum-quantity-of-10=Expensive items have a maximum quantity of 10. +this-item-has-a-maximum-quantity-of-10=This item has a maximum quantity of 10. +``` ## Conclusion -Congratulations! You now know the basics for implementing the `Foo` interface. basic payment method to Liferay Commerce. +Congratulations! You now know the basics for implementing the `CommerceOrderValidator` interface, and have added a new order validator to Liferay Commerce. ## Additional Information + +[Localizing Your Application](https://help.liferay.com/hc/en-us/articles/360018168251-Localizing-Your-Application) + +[Products](https://commerce.liferay.dev/user-guide/-/knowledge_base/user/products) diff --git a/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/images/01.png b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/images/01.png new file mode 100644 index 00000000..ed6a4c60 Binary files /dev/null and b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/images/01.png differ diff --git a/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/build.gradle b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/build.gradle new file mode 100644 index 00000000..56fc79db --- /dev/null +++ b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/build.gradle @@ -0,0 +1,15 @@ +buildscript { + dependencies { + classpath group: "com.liferay", name: "com.liferay.gradle.plugins.defaults", version: "latest.release" + } + + repositories { + mavenLocal() + + maven { + url "https://repository-cdn.liferay.com/nexus/content/groups/public" + } + } +} + +apply plugin: "com.liferay.root.defaults.plugin" diff --git a/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/gradle/wrapper/gradle-wrapper.jar b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..29953ea1 Binary files /dev/null and b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/gradle/wrapper/gradle-wrapper.jar differ diff --git a/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/gradle/wrapper/gradle-wrapper.properties b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..e0b3fb8d --- /dev/null +++ b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/gradlew b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/gradlew new file mode 100644 index 00000000..cccdd3d5 --- /dev/null +++ b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +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 +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +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 + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/gradlew.bat b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/gradlew.bat new file mode 100644 index 00000000..f9553162 --- /dev/null +++ b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/n9b2-impl/bnd.bnd b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/n9b2-impl/bnd.bnd new file mode 100644 index 00000000..f1fae5be --- /dev/null +++ b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/n9b2-impl/bnd.bnd @@ -0,0 +1,3 @@ +Bundle-Name: Acme N9B2 Commerce Order Validator +Bundle-SymbolicName: com.acme.n9b2.internal.commerce.order.validator +Bundle-Version: 1.0.0 \ No newline at end of file diff --git a/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/n9b2-impl/build.gradle b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/n9b2-impl/build.gradle new file mode 100644 index 00000000..43e717d5 --- /dev/null +++ b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/n9b2-impl/build.gradle @@ -0,0 +1,10 @@ +dependencies { + compileOnly group: "biz.aQute.bnd", name: "biz.aQute.bndlib", version: "3.5.0" + compileOnly group: "com.liferay.commerce", name: "com.liferay.commerce.api", version: "9.0.0" + compileOnly group: "com.liferay.commerce", name: "com.liferay.commerce.product.api", version: "10.0.0" + compileOnly group: "com.liferay.portal", name: "com.liferay.util.taglib", version: "3.0.0" + compileOnly group: "com.liferay.portal", name: "release.portal.api", version: "7.1.1" + compileOnly group: "javax.servlet", name: "javax.servlet-api", version: "3.0.1" + compileOnly group: "org.osgi", name: "org.osgi.core", version: "5.0.0" + compileOnly group: "org.osgi", name: "org.osgi.service.component.annotations", version: "1.3.0" +} \ No newline at end of file diff --git a/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/n9b2-impl/src/main/java/com/acme/n9b2/internal/commerce/order/validator/N9B2CommerceOrderValidator.java b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/n9b2-impl/src/main/java/com/acme/n9b2/internal/commerce/order/validator/N9B2CommerceOrderValidator.java new file mode 100644 index 00000000..9ddcc972 --- /dev/null +++ b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/n9b2-impl/src/main/java/com/acme/n9b2/internal/commerce/order/validator/N9B2CommerceOrderValidator.java @@ -0,0 +1,81 @@ +package com.acme.n9b2.internal.commerce.order.validator; + +import com.liferay.commerce.model.CommerceOrder; +import com.liferay.commerce.model.CommerceOrderItem; +import com.liferay.commerce.order.CommerceOrderValidator; +import com.liferay.commerce.order.CommerceOrderValidatorResult; +import com.liferay.commerce.product.model.CPInstance; +import com.liferay.portal.kernel.exception.PortalException; +import com.liferay.portal.kernel.language.LanguageUtil; +import com.liferay.portal.kernel.util.ResourceBundleUtil; + +import org.osgi.service.component.annotations.Component; + +import java.math.BigDecimal; + +import java.util.Locale; +import java.util.ResourceBundle; + +@Component( + immediate = true, + property = { + "commerce.order.validator.key=" + N9B2CommerceOrderValidator.KEY, + "commerce.order.validator.priority:Integer=9" + }, + service = CommerceOrderValidator.class +) +public class N9B2CommerceOrderValidator implements CommerceOrderValidator { + + public static final String KEY = "example"; + + @Override + public String getKey() { + return KEY; + } + + @Override + public CommerceOrderValidatorResult validate( + Locale locale, CommerceOrder commerceOrder, CPInstance cpInstance, + int quantity) + throws PortalException { + + if (cpInstance == null) { + return new CommerceOrderValidatorResult(false); + } + + BigDecimal price = cpInstance.getPrice(); + + if (price.doubleValue() > 100.0 && (quantity > 10)) { + ResourceBundle resourceBundle = ResourceBundleUtil.getBundle( + "content.Language", locale, getClass()); + + return new CommerceOrderValidatorResult( + false, LanguageUtil.get( + resourceBundle, "this-item-has-a-maximum-quantity-of-10")); + } + + return new CommerceOrderValidatorResult(true); + } + + @Override + public CommerceOrderValidatorResult validate( + Locale locale, CommerceOrderItem commerceOrderItem) + throws PortalException { + + BigDecimal price = commerceOrderItem.getUnitPrice(); + + if (price.doubleValue() > 100.0 && + commerceOrderItem.getQuantity() > 10) { + + ResourceBundle resourceBundle = ResourceBundleUtil.getBundle( + "content.Language", locale, getClass()); + + return new CommerceOrderValidatorResult( + false, LanguageUtil.get( + resourceBundle, + "expensive-items-have-a-maximum-quantity-of-10")); + } + + return new CommerceOrderValidatorResult(true); + } +} diff --git a/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/n9b2-impl/src/main/resources/content/Language.properties b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/n9b2-impl/src/main/resources/content/Language.properties new file mode 100644 index 00000000..0a9fb6a8 --- /dev/null +++ b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/n9b2-impl/src/main/resources/content/Language.properties @@ -0,0 +1,2 @@ +expensive-items-have-a-maximum-quantity-of-10=Expensive items have a maximum quantity of 10. +this-item-has-a-maximum-quantity-of-10=This item has a maximum quantity of 10. \ No newline at end of file diff --git a/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/n9b2-impl/src/main/resources/content/Language_en.properties b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/n9b2-impl/src/main/resources/content/Language_en.properties new file mode 100644 index 00000000..0a9fb6a8 --- /dev/null +++ b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/n9b2-impl/src/main/resources/content/Language_en.properties @@ -0,0 +1,2 @@ +expensive-items-have-a-maximum-quantity-of-10=Expensive items have a maximum quantity of 10. +this-item-has-a-maximum-quantity-of-10=This item has a maximum quantity of 10. \ No newline at end of file diff --git a/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/settings.gradle b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/settings.gradle new file mode 100644 index 00000000..a0847cce --- /dev/null +++ b/commerce/developer-guide/tutorial/implementing-a-custom-order-validator/liferay-n9b2.zip/settings.gradle @@ -0,0 +1,15 @@ +buildscript { + dependencies { + classpath group: "com.liferay", name: "com.liferay.gradle.plugins.defaults", version: "latest.release" + } + + repositories { + mavenLocal() + + maven { + url "https://repository-cdn.liferay.com/nexus/content/groups/public" + } + } +} + +apply plugin: "com.liferay.settings.plugin"