Cómo crear una regla de descuento para Liferay Commerce - DEV24 - (Parte 2)

DISCLAIMER: This blog  post has Spanish and English version.

                   ... Terminada la parte 1, podemos continuar nuestra jornada a través de la extensión del módulo ...

Paso 4 - Haciendo la edad configurable

Para tener un módulo reutilizable, podemos hacer la edad configurable y eliminar el valor establecido “a fuego”. Siguiendo estos pasos, aprenderás a hacerlo:

1.  En la carpeta resources folder (i.e.: liferay-workspace-7-3/modules/commerce-discount-rule-by-age/src/main/resources), crea dos nuevas carpetas: la primera con nombre “META-INF” y la segunda y dentro de la anterior, con nombre “resources”.

2.  Dentro de “META-INF/resources crea un nuevo fichero JSP con nombre “init.jsp” y another JSP otro con nombre “view.jsp” 

3.  En el fichero “init.jsp”, copia y pega la línea siguiente para importar la taglib de aui (que será usada en el fichero view.jsp):

<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>

4.  En el fichero “view.jsp”, copia y pega la linea correspondiente a la entrada para la edad: 

<%@ include file="/init.jsp" %>
<div class="col-12">
    <div class="card d-flex flex-column">
        <h4 class="align-items-center card-header d-flex justify-content-between py-3">
        <liferay-ui:message key="add-minimum-age-to-discount" />
        </h4>
        <div class="card-body flex-fill">
        <aui:input label="minimum-age-to-discount" name="typeSettings" type="text">
          <aui:validator name="digits" />
          <aui:validator name="min">30</aui:validator>
        </aui:input>
        </div>
    </div>
</div>

5.  Incluye las claves “add-minimum-age-to-discount” y “minimum-age-to-discount” utilizadas en el fichero JSP anterior. Incluye las traducciones en los ficheros de propiedades (a continuación la traducción para cada idioma).

  • En Language.properties: 
  • add-minimum-age-to-discount=Add the minimum age to discount
    
    minimum-age-to-discount=Minimum age to apply the discount
  • En Language_es_ES.properties 
  • add-minimum-age-to-discount=Añada la edad mínima para el descuento
    
    minimum-age-to-discount=Edad mínima a aplicar el descuento
  • En Language_pt_BR.properties 
  • add-minimum-age-to-discount=Adicione a idade mínima para o desconto
    
    minimum-age-to-discount=Idade mínima para dar o desconto

6.  Crea un nuevo paquete en tu proyecto con nombre “com.liferay.commerce.discount.rule.by.age.render”.

7.  Crea la clase java “CommerceDiscountRuleTypeJSPContributorRuleByAge” que implemente “CommerceDiscountRuleTypeJSPContributor”.

8.  Implementa el método “render”.

9.  Dentro de la clase crea una variable con la clave:

public static final String KEY = "key-rule-gold-person";
Recuerda: “Esta clave identificará nuestro JSP Contributor, por lo que es importante incluir una clave distinta para cada tipo de regla de descuento, para que Liferay Commerce pueda distinguir la nueva JSP del resto. Si reutilizas una clave que ya está en uso, sobreescribirás la JSP existente.

10.  Anota esta clase como un @Component y dentro, incluye 3 propiedades. Debería quedar como sigue:

@Component(
      immediate = true,
      property = {
              "commerce.discount.rule.type.jsp.contributor.key=" + CommerceDiscountRuleTypeJSPContributorRuleByAge.KEY,
              },service = CommerceDiscountRuleTypeJSPContributor.class
)
  • En el array de propiedades, incluye el parámetro necesario para nuestro JSP contributor:
    • "commerce.discount.rule.type.jsp.contributor.key=" + CommerceDiscountRuleTypeJSPContributorRuleByAge.KEY

 

  •  
  • Como servicio, declara la interfaz para la que estás implementando cl clase:
    • service = CommerceDiscountRuleTypeJSPContributor.class

 

11.  Añade las nuevas dependencias necesarias a tu proyecto. Abre el fichero “build.gradle” y copia y pega la siguiente línea (esta dependencia es necesaria para usar JSPRenderer):

compileOnly group: "com.liferay", name: "com.liferay.frontend.taglib", version: "5.4.3"

12.  En “CommerceDiscountRuleTypeJSPContributorRuleByAge.java”, al final de la clase, inyecta el servicio “JSPRenderer” con la anotación @Reference,

@Reference
private JSPRenderer _jspRenderer;

13.  Después, inyecta el servicio “ServletContext” con la anotación @Reference, y usa el parámetro “target” para referenciar el “Bundle-SymbolicName” (establecido en el fichero bnd.bnd) de tu módulo para localizar la JSP.

@Reference(target="(osgi.web.symbolicname=com.liferay.commerce.discount.rule.by.age)")
private ServletContext _servletContext;

14.  Abre el fichero “bnd.bnd” (ubicado en “liferay-workspace-7-3/modules/commerce-discount-rule-by-age”) y declara un “Web-ContextPath” (el valor debería ser único). De esta forma, tu ServletContext se generará correctamente.

Web-ContextPath: /discount-rule-by-age

15.  Ahora en la clase “CommerceDiscountRuleTypeJSPContributorRuleByAge”, dentro del método render”, pasa el control a “view.jsp” a través del servicio  “_jspRenderer”, como en el código siguiente: 

@Override
public void render(long commerceDiscountId, long commerceDiscountRuleId, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
  _jspRenderer.renderJSP(
          _servletContext, httpServletRequest, httpServletResponse,
          "/view.jsp");
}

16.  Para finalizar este paso, vuelve a la clase “CommerceDiscountRuleByAge” y dentro del método evaluate, recuperaremos el valor y cambiamos el valor “70” establecido a fuego. 

String settingsProperty = commerceDiscountRule.getSettingsProperty(
      commerceDiscountRule.getType());

int ageSetting = Integer.valueOf(settingsProperty);

if(period.getYears() >= ageSetting){
  return true;
}

17.  Guarda y despliega, ejecutando el siguiente comando en tu Liferay Workspace.

liferay-workspace-7-3 % ./gradlew deploy

El código usado en este paso está disponible en la etiqueta “step-4” en mi repo de github. 

Probando:

  • En Liferay Portal/DXP,  abre Menú > Commerce > Descuentos > haz click en el descuento creado previamente. Hacia el final, encontrarás la sección “Reglas”, haz click en “Edit”

  • Rellena el campo con el valor “70” y guarda.

  • Ve a tu sitio de Commerce y pruébalo añadiendo algunos productos al carrito y asegúrate de que todo funciona como estaba previsto.

  • Vuelve a "editar"  tu regla de nuevo y verás que el campo de entrada está vacío .

En el próximo paso, veremos cómo recuperar el valor guardado.  

Último paso - Recuperando el valor de configuración guardado.

1.  Añade dos nuevas dependencias a tu proyecto. Abre el fichero “build.gradle” y copia y pega las siguientes líneas (estas dependencias son necesarias para usar las clases StringPool y BeanParamUtil):

compileOnly group: "com.liferay", name: "com.liferay.petra.string"
compileOnly group: "javax.portlet", name: "portlet-api", version: "3.0.0"

2.  Crea un nuevo paquete en tu proyecto con nombre: “com.liferay.commerce.discount.rule.by.age.display.context”.

3.  Crea una clase java con nombre “CommerceTrainingDiscountRuleDisplayContext.java”.

4.  Al final de la clase, declara 3 variables:

private CommerceDiscountRule _commerceDiscountRule;
private final HttpServletRequest _httpServletRequest;
private final CommerceDiscountRuleService _commerceDiscountRuleService;

​​​​​​5.  Crea un constructor para tu clase que reciba como parámetros “CommerceDiscountRuleService” y “HttpServletRequest”.

public CommerceTrainingDiscountRuleDisplayContext(CommerceDiscountRuleService commerceDiscountRuleService,
    HttpServletRequest httpServletRequest){

  _commerceDiscountRuleService = commerceDiscountRuleService;
  _httpServletRequest = httpServletRequest;
}

6.  Crea un método para recuperar un objeto de tipo “CommerceDiscountRule”, como en el siguiente fragmento de código:

public CommerceDiscountRule getCommerceDiscountRule()
    throws PortalException {

    if (_commerceDiscountRule != null) {
        return _commerceDiscountRule;
    }

    long commerceDiscountRuleId = ParamUtil.getLong(
        _httpServletRequest, "commerceDiscountRuleId");

    if (commerceDiscountRuleId > 0) {
        _commerceDiscountRule =
          _commerceDiscountRuleService.getCommerceDiscountRule(
              commerceDiscountRuleId);
    }

    return _commerceDiscountRule;
  }

7.  Finalmente en esta clase, crea el método “getTypeSettings”, que recuperará el valor almacenado en tu configuración. 

public String getTypeSettings() throws PortalException {
  CommerceDiscountRule commerceDiscountRule = getCommerceDiscountRule();

  if (commerceDiscountRule == null) {
    return StringPool.BLANK;
  }

  String type = BeanParamUtil.getString(
    commerceDiscountRule, _httpServletRequest, "type");

  return commerceDiscountRule.getSettingsProperty(type);
}

8.  Abre “CommerceDiscountRuleTypeJSPContributorRuleByAge.java”, y al final de clase, inyecta el servicio “CommerceDiscountRuleService” con la anotación @Reference.

 @Reference
    private CommerceDiscountRuleService _commerceDiscountRuleService;

9.  En esta clase, ve al método render, crea una instancia de “CommerceDiscountRuleByAgeDisplayContext” e incluyelo “httpServletRequest”, como se muestra a continuación:

CommerceDiscountRuleByAgeDisplayContext CommerceDiscountRuleByAgeDisplayContext =
      new CommerceDiscountRuleByAgeDisplayContext(_commerceDiscountRuleService,httpServletRequest);

httpServletRequest.setAttribute("view.jsp-commerceDiscountRuleByAgeDisplayContext",CommerceDiscountRuleByAgeDisplayContext);

10.  En el fichero “init.jsp”, importa “CommerceDiscountRuleByAgeDisplayContext” (que usarás en view.jsp)

<%@ page import="com.liferay.commerce.discount.rule.by.age.display.context.CommerceDiscountRuleByAgeDisplayContext" %>

11.  En el fichero “view.jsp”, después del include, recupera el objeto “CommerceDiscountRuleByAgeDisplayContext” de la petición, y a través del método “getTypeSetting”, recupera el valor almacenado.

<%@ include file="/init.jsp" %>

<%
CommerceDiscountRuleByAgeDisplayContext commerceDiscountRuleByAgeDisplayContext = (CommerceDiscountRuleByAgeDisplayContext)request.getAttribute("view.jsp-commerceDiscountRuleByAgeDisplayContext");
String value = commerceDiscountRuleByAgeDisplayContext.getTypeSettings();
%>

12.  Finalmente, añade el parámetro value como valor para el input.

<aui:input label="minimum-age-to-discount" name="typeSettings" type="text" value="<%= value %>">

13.  Guarda y despliega ejecutando el siguiente comando en tu Liferay Workspace.

liferay-workspace-7-3 % ./gradlew deploy

​​​​​​

14.  Finalmente si editar de nuevo tu regla, verás el input con el valor almacenado por configuración.

 

El código usado en este paso está disponible en una etiqueta con nombre “last-step” en mi repo de github. 

                                                                                         ...And this is the end...

Espero que te haya gustado. En este tutorial, intenté explicar el paso a paso para que los desarrolladores puedan entenderlo (a los novatos , ¡bienvenidos! ;D ).