de.hybris.platform.customerticketingaddon.controllers.pages.AccountSupportTicketsPageController.java Source code

Java tutorial

Introduction

Here is the source code for de.hybris.platform.customerticketingaddon.controllers.pages.AccountSupportTicketsPageController.java

Source

/*
 * [y] hybris Platform
 *
 * Copyright (c) 2017 SAP SE or an SAP affiliate company.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of SAP
 * ("Confidential Information"). You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the
 * license agreement you entered into with SAP.
 *
 *
 */
package de.hybris.platform.customerticketingaddon.controllers.pages;

import de.hybris.platform.acceleratorstorefrontcommons.annotations.RequireHardLogIn;
import de.hybris.platform.acceleratorstorefrontcommons.breadcrumb.Breadcrumb;
import de.hybris.platform.acceleratorstorefrontcommons.breadcrumb.ResourceBreadcrumbBuilder;
import de.hybris.platform.acceleratorstorefrontcommons.constants.WebConstants;
import de.hybris.platform.acceleratorstorefrontcommons.controllers.ThirdPartyConstants;
import de.hybris.platform.acceleratorstorefrontcommons.controllers.pages.AbstractSearchPageController;
import de.hybris.platform.acceleratorstorefrontcommons.controllers.util.GlobalMessages;
import de.hybris.platform.cms2.exceptions.CMSItemNotFoundException;
import de.hybris.platform.commercefacades.customer.CustomerFacade;
import de.hybris.platform.commercefacades.order.CartFacade;
import de.hybris.platform.commercefacades.order.data.CartData;
import de.hybris.platform.commerceservices.search.pagedata.PageableData;
import de.hybris.platform.commerceservices.search.pagedata.SearchPageData;
import de.hybris.platform.customerticketingaddon.constants.CustomerticketingaddonConstants;
import de.hybris.platform.customerticketingaddon.forms.SupportTicketForm;
import de.hybris.platform.customerticketingfacades.TicketFacade;
import de.hybris.platform.customerticketingfacades.data.StatusData;
import de.hybris.platform.customerticketingfacades.data.TicketData;
import de.hybris.platform.ticket.service.UnsupportedAttachmentException;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
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.servlet.mvc.support.RedirectAttributes;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sap.security.core.server.csi.XSSEncoder;

/**
 * Controller for Customer Support tickets.
 */
@Controller
@RequestMapping("/my-account")
public class AccountSupportTicketsPageController extends AbstractSearchPageController {
    private static final Logger LOG = Logger.getLogger(AccountSupportTicketsPageController.class);

    // CMS Pages
    private static final String SUPPORT_TICKET_CODE_PATH_VARIABLE_PATTERN = "{ticketId:.*}";
    private static final String REDIRECT_TO_SUPPORT_TICKETS_PAGE = REDIRECT_PREFIX + "/my-account/support-tickets";

    @Resource(name = "csAttachmentUploadMaxSize")
    private long maxUploadSizeValue;

    @Resource(name = "accountBreadcrumbBuilder")
    private ResourceBreadcrumbBuilder accountBreadcrumbBuilder;

    @Resource(name = "defaultTicketFacade")
    private TicketFacade ticketFacade;

    @Resource(name = "cartFacade")
    private CartFacade cartFacade;

    @Resource(name = "customerFacade")
    private CustomerFacade customerFacade;

    @Resource(name = "validator")
    private Validator validator;

    @Resource(name = "allowedUploadedFormats")
    private String allowedUploadedFormats;

    /**
     * Lists all tickets
     *
     * @param pageNumber
     * @param showMode
     * @param sortCode
     * @param model
     * @param ticketAdded
     * @return View String
     * @throws CMSItemNotFoundException
     */
    @RequestMapping(value = "/support-tickets", method = RequestMethod.GET)
    @RequireHardLogIn
    public String supportTickets(@RequestParam(value = "page", defaultValue = "0") final int pageNumber,
            @RequestParam(value = "show", defaultValue = "Page") final ShowMode showMode,
            @RequestParam(value = "sort", required = false) final String sortCode,
            @RequestParam(value = "ticketAdded", required = false, defaultValue = "false") final boolean ticketAdded,
            final Model model) throws CMSItemNotFoundException {
        storeCmsPageInModel(model,
                getContentPageForLabelOrId(CustomerticketingaddonConstants.SUPPORT_TICKETS_PAGE));
        setUpMetaDataForContentPage(model,
                getContentPageForLabelOrId(CustomerticketingaddonConstants.SUPPORT_TICKETS_PAGE));
        model.addAttribute(WebConstants.BREADCRUMBS_KEY, accountBreadcrumbBuilder
                .getBreadcrumbs(CustomerticketingaddonConstants.TEXT_SUPPORT_TICKETING_HISTORY));
        model.addAttribute(ThirdPartyConstants.SeoRobots.META_ROBOTS,
                ThirdPartyConstants.SeoRobots.NOINDEX_NOFOLLOW);

        final PageableData pageableData = createPageableData(pageNumber, 5, sortCode, showMode);
        final SearchPageData<TicketData> searchPageData = ticketFacade.getTickets(pageableData);

        populateModel(model, searchPageData, showMode);

        if (ticketAdded) {
            GlobalMessages.addConfMessage(model, CustomerticketingaddonConstants.TEXT_SUPPORT_TICKETING_ADDED);
        }

        return getViewForPage(model);
    }

    @InitBinder
    public void init(final WebDataBinder binder) {
        binder.setBindEmptyMultipartFiles(false);
    }

    /**
     * Used for retrieving page to create a customer support ticket.
     *
     * @param model
     * @return View String
     * @throws CMSItemNotFoundException
     */
    @RequestMapping(value = "/add-support-ticket", method = RequestMethod.GET)
    @RequireHardLogIn
    public String addSupportTicket(final Model model) throws CMSItemNotFoundException {
        storeCmsPageInModel(model,
                getContentPageForLabelOrId(CustomerticketingaddonConstants.ADD_SUPPORT_TICKET_PAGE));
        setUpMetaDataForContentPage(model,
                getContentPageForLabelOrId(CustomerticketingaddonConstants.ADD_SUPPORT_TICKET_PAGE));

        model.addAttribute(WebConstants.BREADCRUMBS_KEY,
                getBreadcrumbs(CustomerticketingaddonConstants.TEXT_SUPPORT_TICKETING_ADD));
        model.addAttribute(ThirdPartyConstants.SeoRobots.META_ROBOTS,
                ThirdPartyConstants.SeoRobots.NOINDEX_NOFOLLOW);
        model.addAttribute(CustomerticketingaddonConstants.SUPPORT_TICKET_FORM, new SupportTicketForm());
        model.addAttribute(CustomerticketingaddonConstants.MAX_UPLOAD_SIZE, Long.valueOf(maxUploadSizeValue));
        model.addAttribute(CustomerticketingaddonConstants.MAX_UPLOAD_SIZE_MB,
                FileUtils.byteCountToDisplaySize(maxUploadSizeValue));
        try {
            model.addAttribute(CustomerticketingaddonConstants.SUPPORT_TICKET_ASSOCIATED_OBJECTS,
                    ticketFacade.getAssociatedToObjects());
            model.addAttribute(CustomerticketingaddonConstants.SUPPORT_TICKET_CATEGORIES,
                    ticketFacade.getTicketCategories());
        } catch (final UnsupportedOperationException ex) {
            LOG.error(ex.getMessage(), ex);
        }

        return getViewForPage(model);
    }

    /**
     * Creates a ticket.
     *
     * @param supportTicketForm
     * @param bindingResult
     * @return View String
     */
    @RequestMapping(value = "/add-support-ticket", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @RequireHardLogIn
    @ResponseBody
    public ResponseEntity<List<Map<String, String>>> addSupportTicket(final SupportTicketForm supportTicketForm,
            final BindingResult bindingResult) {
        validator.validate(supportTicketForm, bindingResult);
        if (bindingResult.hasErrors()) {
            final List<Map<String, String>> list = buildErrorMessagesMap(bindingResult);
            list.add(buildMessageMap(CustomerticketingaddonConstants.FORM_GLOBAL_ERROR_KEY,
                    CustomerticketingaddonConstants.FORM_GLOBAL_ERROR));

            return new ResponseEntity<>(list, HttpStatus.BAD_REQUEST);
        }

        try {
            ticketFacade.createTicket(this.populateTicketData(supportTicketForm));
        } catch (final UnsupportedAttachmentException usAttEx) {
            LOG.error(usAttEx.getMessage(), usAttEx);
            final Map<String, String> map = Maps.newHashMap();
            map.put(CustomerticketingaddonConstants.SUPPORT_TICKET_TRY_LATER,
                    getMessageSource().getMessage(
                            CustomerticketingaddonConstants.TEXT_SUPPORT_TICKETING_ATTACHMENT_BLOCK_LISTED,
                            new Object[] { allowedUploadedFormats }, getI18nService().getCurrentLocale()));
            return new ResponseEntity<>(Lists.newArrayList(map), HttpStatus.BAD_REQUEST);
        } catch (final RuntimeException rEX) {
            final Map<String, String> map = Maps.newHashMap();
            LOG.error(rEX.getMessage(), rEX);

            map.put(CustomerticketingaddonConstants.SUPPORT_TICKET_TRY_LATER,
                    getMessageSource().getMessage(CustomerticketingaddonConstants.TEXT_SUPPORT_TICKETING_TRY_LATER,
                            null, getI18nService().getCurrentLocale()));
            return new ResponseEntity<>(Lists.newArrayList(map), HttpStatus.BAD_REQUEST);
        }

        return new ResponseEntity<>(HttpStatus.OK);

    }

    /**
     * Get Ticket Details.
     *
     * @param ticketId
     * @param model
     * @param redirectModel
     * @param ticketUpdated
     * @return View String
     * @throws CMSItemNotFoundException
     */
    @RequestMapping(value = "/support-ticket/"
            + SUPPORT_TICKET_CODE_PATH_VARIABLE_PATTERN, method = RequestMethod.GET)
    @RequireHardLogIn
    public String getSupportTicket(@PathVariable("ticketId") final String ticketId, final Model model,
            @RequestParam(value = "ticketUpdated", required = false, defaultValue = "false") final boolean ticketUpdated,
            final RedirectAttributes redirectModel) throws CMSItemNotFoundException {
        storeCmsPageInModel(model,
                getContentPageForLabelOrId(CustomerticketingaddonConstants.UPDATE_SUPPORT_TICKET_PAGE));
        setUpMetaDataForContentPage(model,
                getContentPageForLabelOrId(CustomerticketingaddonConstants.UPDATE_SUPPORT_TICKET_PAGE));

        model.addAttribute(WebConstants.BREADCRUMBS_KEY,
                getBreadcrumbs(CustomerticketingaddonConstants.TEXT_SUPPORT_TICKETING_UPDATE));
        model.addAttribute(ThirdPartyConstants.SeoRobots.META_ROBOTS,
                ThirdPartyConstants.SeoRobots.NOINDEX_NOFOLLOW);
        model.addAttribute(CustomerticketingaddonConstants.SUPPORT_TICKET_FORM, new SupportTicketForm());
        model.addAttribute(CustomerticketingaddonConstants.MAX_UPLOAD_SIZE, Long.valueOf(maxUploadSizeValue));
        model.addAttribute(CustomerticketingaddonConstants.MAX_UPLOAD_SIZE_MB,
                FileUtils.byteCountToDisplaySize(maxUploadSizeValue));
        try {
            final TicketData ticketData = ticketFacade.getTicket(XSSEncoder.encodeHTML(ticketId));
            model.addAttribute(CustomerticketingaddonConstants.SUPPORT_TICKET_DATA, ticketData);
        } catch (final Exception e) {
            LOG.error("Attempted to load ticket details that does not exist or is not visible", e);
            GlobalMessages.addFlashMessage(redirectModel, GlobalMessages.ERROR_MESSAGES_HOLDER,
                    CustomerticketingaddonConstants.TEXT_SUPPORT_TICKETING_TRY_LATER, null);
            return REDIRECT_TO_SUPPORT_TICKETS_PAGE;
        }

        if (ticketUpdated) {
            GlobalMessages.addConfMessage(model, CustomerticketingaddonConstants.TEXT_SUPPORT_TICKETING_ADDED);
        }

        return getViewForPage(model);
    }

    /**
     * Updates a ticket with new information from form.
     *
     * @param supportTicketForm
     * @param bindingResult
     * @return View String
     */
    @RequestMapping(value = "/support-ticket/"
            + SUPPORT_TICKET_CODE_PATH_VARIABLE_PATTERN, method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @RequireHardLogIn
    @ResponseBody
    public ResponseEntity<List<Map<String, String>>> updateSupportTicket(final SupportTicketForm supportTicketForm,
            final BindingResult bindingResult) {

        validator.validate(supportTicketForm, bindingResult);

        if (bindingResult.hasErrors()) {
            final List<Map<String, String>> list = buildErrorMessagesMap(bindingResult);
            list.add(buildMessageMap(CustomerticketingaddonConstants.FORM_GLOBAL_ERROR_KEY,
                    CustomerticketingaddonConstants.FORM_GLOBAL_ERROR));
            return new ResponseEntity<>(list, HttpStatus.BAD_REQUEST);
        }

        try {
            ticketFacade.updateTicket(this.populateTicketData(supportTicketForm));
        } catch (final UnsupportedAttachmentException usAttEx) {
            LOG.error(usAttEx.getMessage(), usAttEx);
            final Map<String, String> map = Maps.newHashMap();

            map.put(CustomerticketingaddonConstants.SUPPORT_TICKET_TRY_LATER,
                    getMessageSource().getMessage(
                            CustomerticketingaddonConstants.TEXT_SUPPORT_TICKETING_ATTACHMENT_BLOCK_LISTED,
                            new Object[] { allowedUploadedFormats }, getI18nService().getCurrentLocale()));
            return new ResponseEntity<>(Lists.newArrayList(map), HttpStatus.BAD_REQUEST);
        } catch (final RuntimeException rEx) {
            LOG.error(rEx.getMessage(), rEx);
            //Assuming there might have been an error occurred, If ticket data returned as null. Return to the update page.
            final Map<String, String> map = Maps.newHashMap();
            map.put(CustomerticketingaddonConstants.SUPPORT_TICKET_TRY_LATER,
                    getMessageSource().getMessage(CustomerticketingaddonConstants.TEXT_SUPPORT_TICKETING_TRY_LATER,
                            null, getI18nService().getCurrentLocale()));
            return new ResponseEntity<>(Lists.newArrayList(map), HttpStatus.BAD_REQUEST);
        }

        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * Populated the data from the form bean to ticket data object.
     *
     * @param supportTicketForm
     * @return TicketData
     */
    protected TicketData populateTicketData(final SupportTicketForm supportTicketForm) // TODO: should be moved to populator class
    {
        final TicketData ticketData = new TicketData();
        if (cartFacade.hasSessionCart()) {
            final CartData cartData = cartFacade.getSessionCart();
            if (!cartData.getEntries().isEmpty()) {
                ticketData.setCartId(cartData.getCode());
            }
        }
        if (StringUtils.isNotBlank(supportTicketForm.getId())) {
            ticketData.setId(supportTicketForm.getId());
        }
        final StatusData status = new StatusData();
        status.setId(supportTicketForm.getStatus());
        ticketData.setStatus(status);
        ticketData.setCustomerId(customerFacade.getCurrentCustomerUid());
        ticketData.setSubject(supportTicketForm.getSubject());
        ticketData.setMessage(supportTicketForm.getMessage());
        ticketData.setAssociatedTo(supportTicketForm.getAssociatedTo());
        ticketData.setTicketCategory(supportTicketForm.getTicketCategory());
        ticketData.setAttachments(supportTicketForm.getFiles());
        return ticketData;
    }

    protected List<Breadcrumb> getBreadcrumbs(final String breadcrumbCode) {
        final List<Breadcrumb> breadcrumbs = accountBreadcrumbBuilder.getBreadcrumbs(null);
        breadcrumbs.add(new Breadcrumb("/my-account/support-tickets",
                getMessageSource().getMessage(CustomerticketingaddonConstants.TEXT_SUPPORT_TICKETING_HISTORY, null,
                        getI18nService().getCurrentLocale()),
                null));
        breadcrumbs.add(new Breadcrumb("#",
                getMessageSource().getMessage(breadcrumbCode, null, getI18nService().getCurrentLocale()), null));
        return breadcrumbs;
    }

    /**
     * Build the error message list with map contains the validation error code and localised message.
     *
     * @param bindingResult
     * @return Map of error code and message
     */
    protected List<Map<String, String>> buildErrorMessagesMap(final BindingResult bindingResult) {
        return bindingResult.getAllErrors().stream()
                .filter(err -> err.getCode() != null && err.getCode().length() > 0).map(err -> {
                    final Map<String, String> map = Maps.newHashMap();
                    map.put(err.getCodes()[0].replaceAll("\\.", "-"), err.getDefaultMessage());
                    return map;
                }).collect(Collectors.toList());
    }

    /**
     * Build a map with key and localsed Message.
     *
     * @param key
     *           the render key
     * @param localisedKey
     *           the localised message key
     * @return Map of error code and message
     */
    protected Map<String, String> buildMessageMap(final String key, final String localisedKey) {
        final Map<String, String> map = Maps.newHashMap();
        map.put(key, getMessageSource().getMessage(localisedKey, null, getI18nService().getCurrentLocale()));

        return map;
    }
}