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

Java tutorial

Introduction

Here is the source code for com.nec.harvest.controller.TanaoroshiController.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.Collections;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
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.InventoryBean;
import com.nec.harvest.bean.mapping.json.JSONBean;
import com.nec.harvest.bean.mapping.json.JSONInventory;
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.service.InventoryService;
import com.nec.harvest.service.TightenService;
import com.nec.harvest.stereotype.SessionAttribute;
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 inventory report screen
 * 
 * @author sondn
 * 
 */
@Controller
@RequestMapping(value = Constants.TANAOROSHI_PATH)
public class TanaoroshiController extends DailyReportingProGroup implements AbstractRenderer, TitleRenderer {

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

    private static final String INVENTORY_CATEGORY = "inventories";

    private final InventoryService inventoryService;

    private final TightenService tightenService;

    @Inject
    public TanaoroshiController(InventoryService inventoryService, TightenService tightenService) {
        this.inventoryService = inventoryService;
        this.tightenService = tightenService;
    }

    /**
     * Default mapping without path variables for Sales report 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) {
        if (logger.isDebugEnabled()) {
            logger.debug("Redering stocktake report...");
        }

        // 
        logger.info("Redering category amount screen with default path...");

        // Automatically build a redirect link
        UriComponents uriComponents = UriComponentsBuilder
                .fromUriString(Constants.TANAOROSHI_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 inventory management screen with params in session...");
        return "redirect:" + uri.toString();
    }

    /**
     * This function will be mapped with URL {@link /tanaoroshi/{orgCode}
     * /{businessDay}}, it can be used to render the Sales report with a month for a
     * shop. Will be displayed a message when have a exception or an error
     * occurred.
     * 
     * @param orgCode
     *            Shop's code
     * @param businessDay
     *            Business Day (Date time with format yyyyMM)
     * @param model
     *            Spring's model that can be used to render a view
     * @return A view name
     */
    @RequestMapping(value = "/{orgCode}/{monthly}", 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);

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

        try {
            String monthYear = DateFormatUtil.format(monthly, DateFormat.DATE_WITHOUT_DAY);
            inventories = getInventoriesOfMonthly(orgCode, monthYear);
            // 
            logger.info("Found {} inventories for organization {} in {}", inventories.size(), orgCode, businessDay);
        } 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();
        }

        // The following source code will be detected the end-user can be changed
        // the inventory 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 inventory 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();
        }

        try {
            String nextMonthly = BusinessDayHelper.getNextMonthly(monthly, DateFormat.DATE_WITHOUT_DAY);

            // Should disable the "NEXT MONTH" button if there is no inventory detail
            List<InventoryBean> inventoriesNextMonth = getInventoriesOfMonthly(orgCode, nextMonthly);
            if (CollectionUtils.isNotEmpty(inventoriesNextMonth)) {
                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();
        }

        try {
            String prevMonthly = BusinessDayHelper.getPreviousMonthly(monthly, DateFormat.DATE_WITHOUT_DAY);

            // Should disable the "PREVIOUS MONTH" button if there is no inventory data
            List<InventoryBean> cashesOfPrevMonthly = getInventoriesOfMonthly(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();
        }
        if (CollectionUtils.isEmpty(inventories)) {
            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(INVENTORY_CATEGORY, inventories);
            return getViewName();
        } else {
            model.addAttribute(INVENTORY_CATEGORY, inventories);
        }
        return getViewName();
    }

    /**
     This function will be mapped with register action on Invetory report 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
     *            Originazation's code
     * @param businessDay
     *            Business Day (Date time with format YYYYMM)
     * @param arrJSONInventory
     *            A map of parameters from client form (including a list of
     *            inventories, hidden input, ...)
     * @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}/{monthly}", method = RequestMethod.POST)
    public @ResponseBody JSONBean saveTanaData(@PathVariable String proGNo, @PathVariable String orgCode,
            @PathVariable @DateTimeFormat(pattern = "yyyyMM") Date monthly,
            @RequestBody final JSONInventory[] arrJSONInventory, final Model model) {

        if (logger.isDebugEnabled()) {
            logger.debug("Updating the inventory 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 (JSONInventory jsonInventory : arrJSONInventory) {
                int currentUpdNo = 0;
                try {
                    currentUpdNo = inventoryService.findUpdNoByOrgCodeAndMonthAndCtgCode(orgCode, monthYear,
                            jsonInventory.getCtgCode());
                } catch (IllegalArgumentException ex) {
                    logger.error(ex.getMessage(), ex);

                    return new JSONBean(Boolean.FALSE, "", MessageHelper.get(MsgConstants.CM_UPD_M03));
                } catch (ServiceException ex) {
                    logger.error(ex.getMessage(), ex);

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

                if (currentUpdNo > jsonInventory.getUpdNo()) {
                    return new JSONBean(Boolean.FALSE, "", MessageHelper.get(MsgConstants.CM_UPD_M01));
                }

                try {
                    boolean updateStatus = inventoryService.updateByOrgCodeAndMonthlyAndCtgCode(session, orgCode,
                            monthYear, jsonInventory);
                    // if updateStatus = false then update unsuccessfully
                    if (!updateStatus) {
                        return new JSONBean(Boolean.FALSE, "", MessageHelper.get(MsgConstants.CM_UPD_M03));
                    }
                } catch (IllegalArgumentException ex) {
                    if (tx != null) {
                        tx.rollback();
                    }
                    // exception when execute query
                    return new JSONBean(Boolean.FALSE, "", MessageHelper.get(MsgConstants.CM_UPD_M03));
                } catch (ServiceException ex) {
                    if (tx != null) {
                        tx.rollback();
                    }
                    // ???????????
                    return new JSONBean(Boolean.FALSE, "", getSystemError());
                }
            }

            tx.commit();
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);

            // Rollback
            if (tx != null) {
                tx.rollback();
            }
            return new JSONBean(Boolean.FALSE, "", MessageHelper.get(MsgConstants.CM_UPD_M03));
        } finally {
            // ?
            HibernateSessionManager.closeSession(session);
        }
        return new JSONBean(Boolean.TRUE, "", MessageHelper.get(MsgConstants.CM_UPD_M02));
    }

    /**
     * Get a list of inventories of a month for a shop. Return a empty list if
     * could not find any inventory.
     * 
     * @param shopCode
     *            Shop's code
     * @param businessDay
     *            Business Day (Date time with format YYYYMM)
     * @return A list of inventories
     */
    protected List<InventoryBean> getInventoriesOfMonthly(String shopCode, String businessDay) {
        if (StringUtils.isEmpty(shopCode) || StringUtils.isEmpty(businessDay)) {
            return Collections.emptyList();
        }

        List<InventoryBean> inventories = inventoryService.findByOrgCodeAndMonth(shopCode, businessDay);
        if (!inventories.isEmpty()) {
            Collections.sort(inventories);

            // Return
            return inventories;
        }
        return Collections.emptyList();
    }

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

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