com.nec.harvest.controller.GenkinController.java Source code

Java tutorial

Introduction

Here is the source code for com.nec.harvest.controller.GenkinController.java

Source

/**
 * Copyright(C) 2014
 * NEC Corporation All rights reserved.
 * 
 * No permission to use, copy, modify and distribute this software
 * and its documentation for any purpose is granted.
 * This software is provided under applicable license agreement only.
 */
package com.nec.harvest.controller;

import java.net.URI;
import java.text.ParseException;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;

import org.apache.commons.collections.CollectionUtils;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import com.nec.core.exception.ObjectNotFoundException;
import com.nec.core.exception.TooManyObjectsException;
import com.nec.crud.hibernate.HibernateSessionManager;
import com.nec.harvest.bean.mapping.CashBean;
import com.nec.harvest.bean.mapping.json.JSONBean;
import com.nec.harvest.bean.mapping.json.JSONCash;
import com.nec.harvest.constant.Constants;
import com.nec.harvest.constant.MsgConstants;
import com.nec.harvest.exception.ServiceException;
import com.nec.harvest.helper.BusinessDayHelper;
import com.nec.harvest.helper.MessageHelper;
import com.nec.harvest.menu.group.DailyReportingProGroup;
import com.nec.harvest.model.Tighten;
import com.nec.harvest.model.User;
import com.nec.harvest.service.CashService;
import com.nec.harvest.service.MonthlySalesService;
import com.nec.harvest.service.TightenService;
import com.nec.harvest.stereotype.MaskFormat;
import com.nec.harvest.stereotype.SessionAttribute;
import com.nec.harvest.stereotype.UserPrincipal;
import com.nec.harvest.util.DateFormatUtil;
import com.nec.harvest.util.DateFormatUtil.DateFormat;
import com.nec.harvest.util.DateUtil;

/**
 * This is a controller which allow handle all events on the cash management screen
 * 
 * 
 * @author <a href="mailto:sondn@nec.vn">Ngoc Son Dang</a>
 * @version GenkinController.java
 * @since 2014/06/09
 *
 */
@Controller
@RequestMapping(value = Constants.GENKIN_PATH)
public class GenkinController extends DailyReportingProGroup implements AbstractRenderer, TitleRenderer {

    private static final Logger logger = LoggerFactory.getLogger(GenkinController.class);

    private static final String LIST_GENKIN_BEAN = "listGenkinBean";
    private static final String COUNT_DATE = "countDate";

    private final CashService cashService;

    private final TightenService tightenService;

    private final MonthlySalesService monthlySalesService;

    @Inject
    public GenkinController(CashService cashService, TightenService tightenService,
            MonthlySalesService monthlySalesService) {
        this.cashService = cashService;
        this.tightenService = tightenService;
        this.monthlySalesService = monthlySalesService;
    }

    /**
     * Default mapping without path variables for Cash management screen
     * 
     * @param request
     *            HttpServletRequest
     * @param response
     *            HttpServletResponse
     * @param model
     *            Spring model that can be used to render a view
     * @return A redirect URL
     */
    @Override
    @RequestMapping(value = "", method = RequestMethod.GET)
    public String render(@SessionAttribute(Constants.SESS_ORGANIZATION_CODE) String userOrgCode,
            @SessionAttribute(Constants.SESS_BUSINESS_DAY) Date businessDay, @PathVariable String proGNo) {
        logger.info("Redering cash management screen with default path...");

        // Automatically build a redirect link
        UriComponents uriComponents = UriComponentsBuilder
                .fromUriString(Constants.GENKIN_PATH + "/{orgCode}/{monthly}").build();
        String businessDate = DateFormatUtil.format(businessDay, DateFormat.DATE_WITHOUT_DAY);
        URI uri = uriComponents.expand(proGNo, userOrgCode, businessDate).encode().toUri();

        logger.info("Redirect to cash management screen with params in session...");
        return "redirect:" + uri.toString();
    }

    /**
     * Handling the path /{orgCode}/{monthly}
     * 
     * @param businessDay
     *            Business day
     * @param orgCode
     *            Actual organization's code
     * @param monthly
     *            Actual processing monthly
     * @param model
     * @return The view name of Cash Management
     */
    @RequestMapping(value = "/{orgCode:[a-z0-9]+}/{monthly:[\\d]+}", method = RequestMethod.GET)
    public String render(@SessionAttribute(Constants.SESS_BUSINESS_DAY) Date businessDay,
            @PathVariable String proGNo, @PathVariable String orgCode,
            @PathVariable @DateTimeFormat(pattern = "yyyyMM") Date monthly, final Model model) {
        if (logger.isDebugEnabled()) {
            logger.debug("Redering cash management screen for the organization " + orgCode);
        }

        // 
        model.addAttribute(PROCESSING_MONTH, monthly);
        model.addAttribute(COUNT_DATE, getActualMaximumDayOfMonth(monthly));

        // Should disable the "NEXT MONTH" button if there is no cash data
        try {
            String nextMonthly = BusinessDayHelper.getNextMonthly(monthly, DateFormat.DATE_WITHOUT_DAY);
            List<CashBean> cashesOfNextMonthly = cashService.findByOrgCodeAndMonth(orgCode, nextMonthly);
            if (CollectionUtils.isNotEmpty(cashesOfNextMonthly)) {
                model.addAttribute(NEXT_MONTH, nextMonthly);
            }
        } catch (IllegalArgumentException | ObjectNotFoundException ex) {
            logger.warn(ex.getMessage());

            model.addAttribute(NEXT_MONTH, null);
        } catch (ServiceException ex) {
            logger.error(ex.getMessage(), ex);

            // ???????????
            model.addAttribute(ERROR, Boolean.TRUE);
            model.addAttribute(ERROR_MESSAGE, getSystemError());
            return getViewName();
        }

        // Should disable the "PREVIOUS MONTH" button if there is no cash data
        try {
            String prevMonthly = BusinessDayHelper.getPreviousMonthly(monthly, DateFormat.DATE_WITHOUT_DAY);
            List<CashBean> cashesOfPrevMonthly = cashService.findByOrgCodeAndMonth(orgCode, prevMonthly);
            if (CollectionUtils.isNotEmpty(cashesOfPrevMonthly)) {
                model.addAttribute(PREVIOUS_MONTH, prevMonthly);
            }
        } catch (IllegalArgumentException | ObjectNotFoundException ex) {
            logger.warn(ex.getMessage());

            model.addAttribute(PREVIOUS_MONTH, null);
        } catch (ServiceException ex) {
            logger.error(ex.getMessage(), ex);

            // ???????????
            model.addAttribute(ERROR, Boolean.TRUE);
            model.addAttribute(ERROR_MESSAGE, getSystemError());
            return getViewName();
        }

        // A list of cashes in monthly for a organization,
        // will be returned null or empty if not found any object for the monthly
        List<CashBean> cashes = null;

        try {
            String monthYear = DateFormatUtil.format(monthly, DateFormat.DATE_WITHOUT_DAY);
            cashes = cashService.findByOrgCodeAndMonth(orgCode, monthYear);
        } catch (IllegalArgumentException | ObjectNotFoundException ex) {
            logger.warn(ex.getMessage());

        } catch (ServiceException ex) {
            logger.error(ex.getMessage(), ex);

            // ???????????
            model.addAttribute(ERROR, Boolean.TRUE);
            model.addAttribute(ERROR_MESSAGE, getSystemError());
            return getViewName();
        }

        if (CollectionUtils.isEmpty(cashes)) {
            if (logger.isDebugEnabled()) {
                logger.debug(
                        "sales data of organization code: " + orgCode + " on month: " + monthly + " is not exist.");
            }
            model.addAttribute(ERROR, true);
            model.addAttribute(ERROR_MESSAGE, MessageHelper.get(MsgConstants.CM_QRY_M01));
            model.addAttribute(EDITABLE, Boolean.FALSE);
            model.addAttribute(LIST_GENKIN_BEAN, cashes);
            return getViewName();
        } else {
            model.addAttribute(LIST_GENKIN_BEAN, cashes);
        }

        // The following source code will be detected the end-user can be changed
        // the cashes data or not. If the data already pushed into Tighten table 
        // so that means end-user can not modify the data. Otherwise that is Boolean.TRUE
        Tighten tighten = null;

        try {
            tighten = tightenService.findByClassifyAndMonth("1");

            // The final month year of tighten
            String sudoOfTighten = tighten.getGetSudo();
            try {
                Date monthlyOfTighten = DateFormatUtil.parse(sudoOfTighten, DateFormat.DATE_WITHOUT_DAY);
                model.addAttribute(EDITABLE, monthly.after(monthlyOfTighten));
            } catch (NullPointerException | ParseException ex) {
                logger.warn(ex.getMessage(), ex);

                // The default is can be edited
                model.addAttribute(EDITABLE, Boolean.TRUE);
            }
        } catch (IllegalArgumentException | ObjectNotFoundException ex) {
            logger.warn(ex.getMessage());

            // If the cashes data is not push into the Tighten that means can edit 
            // current data. So the EDITABLE should being Boolean.TRUE
            Date monthsToSubtract = DateUtil.monthsToSubtract(businessDay, 3);
            model.addAttribute(EDITABLE, monthly.after(monthsToSubtract));
        } catch (TooManyObjectsException ex) {
            logger.warn(ex.getMessage(), ex);

            // The default is can be edited
            model.addAttribute(EDITABLE, Boolean.TRUE);
        } catch (ServiceException ex) {
            logger.error(ex.getMessage(), ex);

            // ???????????
            model.addAttribute(ERROR, Boolean.TRUE);
            model.addAttribute(ERROR_MESSAGE, getSystemError());
            return getViewName();
        }

        return getViewName();
    }

    /**
    * This function will be mapped with save action on cash management screen.
    * If all are valid then it will be updated all the changed information into
    * the DB and inform a successfully updated message
    * 
    * @param orgCode
    *            Organization code
    * @param monthly
    *            Date time with format YYYYMM
    * @param parameters
    *            A list of parameters from client form
    * @param model
    *            Spring's model that can be used to render a view
    * @return JSON object to let client know actual status of request
    */
    @RequestMapping(value = "/save/{orgCode:[a-z0-9]+}/{monthly:[\\d]+}", method = RequestMethod.POST)
    public @ResponseBody JSONBean onSubmit(@UserPrincipal User user, @PathVariable String proGNo,
            @PathVariable String orgCode, @PathVariable @DateTimeFormat(pattern = "yyyyMM") Date monthly,
            @RequestBody final JSONCash[] arrJSONCash, final Model model) {
        if (logger.isDebugEnabled()) {
            logger.debug("Updating the cash data in monthly {} into the DB for organization {}...", monthly,
                    orgCode);
        }

        final Session session = HibernateSessionManager.getSession();
        Transaction tx = null;

        try {
            tx = session.beginTransaction();

            String monthYear = DateFormatUtil.format(monthly, DateFormat.DATE_WITHOUT_DAY);
            for (JSONCash jSONCash : arrJSONCash) {
                // This code will be used to detect during in processing time the current record 
                // have been updated by someone else or not            
                try {
                    int currentUpdNo = cashService.findUpdNoByOrgCodeAndMonthAndSrDate(orgCode, monthYear,
                            jSONCash.getSrDate());
                    if (currentUpdNo > jSONCash.getUpdNo()) {
                        return new JSONBean(Boolean.FALSE, "", MessageHelper.get(MsgConstants.CM_UPD_M01));
                    }
                } catch (IllegalArgumentException | ServiceException ie) {
                    logger.error("An exception occured while check updNo the cash data in monthly for organization"
                            + orgCode, ie);

                    // ???????????
                    return new JSONBean(Boolean.FALSE, "", getSystemError());
                }

                try {
                    boolean actualUpdateState = cashService.updateCashByOrgCodeAndDate(session, user, jSONCash,
                            monthYear);
                    if (!actualUpdateState) {
                        return new JSONBean(Boolean.FALSE, "", MessageHelper.get(MsgConstants.CM_UPD_M03));
                    }
                } catch (IllegalArgumentException | ServiceException e) {
                    logger.error("An exception occured while updating the cash data in monthly for organization"
                            + orgCode, e);

                    // Rollback
                    if (tx != null) {
                        tx.rollback();
                    }
                    return new JSONBean(Boolean.FALSE, "", MessageHelper.get(MsgConstants.CM_UPD_M03));
                }

            }
            tx.commit();
        } catch (ServiceException ex) {
            logger.error("An exception occured while updating the cash data in monthly for organization" + orgCode,
                    ex);
            if (tx != null) {
                tx.rollback();
            }
            // ???????????
            return new JSONBean(Boolean.FALSE, "", getSystemError());
        } finally {
            // ?
            HibernateSessionManager.closeSession(session);
        }

        return new JSONBean(Boolean.TRUE, "", MessageHelper.get(MsgConstants.CM_UPD_M02));
    }

    /**
     * ?? 
     * 
     * @param orgCode
     *            Organization code
     * @param month
     *            Date time with format YYYYMM
     * @param params
     *            A list of parameters from client form
     * @param model
     * @return JSON object to let client know actual status of request
     */
    @RequestMapping(value = "/check-monthly-cash/{orgCode:[a-z0-9]+}/{monthly:[\\d]+}", method = RequestMethod.GET)
    public @ResponseBody JSONBean onCheckMontlyCash(@PathVariable String proGNo, @PathVariable String orgCode,
            @PathVariable @MaskFormat("######") String monthly) {
        if (logger.isDebugEnabled()) {
            logger.debug("Check monthly sales for organization {}...", orgCode);
        }

        try {
            int monthlyCash = monthlySalesService.findByOrgCodeAndMonth(orgCode, monthly);
            return new JSONBean(Boolean.TRUE, "",
                    MessageHelper.get(monthlyCash > 0 ? MsgConstants.CM_CFM_REG_M02 : MsgConstants.CM_CFM_REG_M01));
        } catch (IllegalArgumentException | ServiceException ex) {
            logger.warn(ex.getMessage());

            // ???????????
            return new JSONBean(Boolean.FALSE, "", getSystemError());
        }
    }

    @Override
    public String getViewName() {
        return "genkin/genkin";
    }

    @Override
    public String getTitleName() {
        return "??";
    }
}