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

Java tutorial

Introduction

Here is the source code for com.nec.harvest.controller.JisekimController.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.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.exception.SQLGrammarException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.MediaType;
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.ActualViewABean;
import com.nec.harvest.bean.mapping.ActualViewBean;
import com.nec.harvest.bean.mapping.json.JSONActualViewBean;
import com.nec.harvest.bean.mapping.json.JSONBean;
import com.nec.harvest.bean.mapping.json.JSONListActualViewBean;
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.ProfitAndLossManagementProGroup;
import com.nec.harvest.model.Organization;
import com.nec.harvest.model.Tighten;
import com.nec.harvest.service.ActualViewService;
import com.nec.harvest.service.InventoryService;
import com.nec.harvest.service.MonthlySalesService;
import com.nec.harvest.service.OrganizationService;
import com.nec.harvest.service.PurchaseService;
import com.nec.harvest.service.TightenService;
import com.nec.harvest.stereotype.MaskFormat;
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 jisekim screen
 * 
 * @author QuanDK
 * 
 */
@Controller
@RequestMapping(Constants.JISEKIM_PATH)
public class JisekimController extends ProfitAndLossManagementProGroup implements PageRenderer, TitleRenderer {

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

    private static final String SELECTED_ORG_CODE = "selectedCode";
    private static final String SALES_BEANS_B = "salesBeansB";
    private static final String SALES_BEANS_C = "salesBeansC";
    private static final String PURCHASES_DATA_30 = "purchases30";
    private static final String PURCHASES_DATA_60 = "purchases60";
    private static final String INVENTORY_DATA = "inventories";
    private static final String ORGNIZATIONS = "organizations";
    private static final String ACTUAL_VIEW_A = "actualViewA";

    private final ActualViewService actualViewService;

    private final OrganizationService organizationService;

    private final TightenService tightenService;

    private final InventoryService inventoryService;

    private final PurchaseService purchaseService;

    private final MonthlySalesService monthlySalesService;

    @Inject
    public JisekimController(ActualViewService actualViewService, OrganizationService organizationService,
            TightenService tightenService, InventoryService inventoryService, PurchaseService purchaseService,
            MonthlySalesService monthlySalesService) {
        this.actualViewService = actualViewService;
        this.organizationService = organizationService;
        this.tightenService = tightenService;
        this.inventoryService = inventoryService;
        this.purchaseService = purchaseService;
        this.monthlySalesService = monthlySalesService;
    }

    /**
     * Default mapping without path variables for Jisekim screen
     * 
     * @param userOrgCode
     * @param businessDay
     * @param proGNo
     * @param request
     * @param response
     * @param model
     * @return String redirect Uri
     */
    @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,
            final Model model) {
        if (logger.isDebugEnabled()) {
            logger.debug("Redering Jisekim report without parameters...");
        }

        logger.info("Trying to generate the Jisekim template for monthly {} and organization code {}", userOrgCode);

        // NOT EDIT
        model.addAttribute(EDITABLE, Boolean.FALSE);

        // Get list Organization for select box
        List<Organization> organizations;
        try {
            logger.info("Trying to get a list of organization for the given kaisobango {}",
                    Constants.DEFAULT_KAISOBANGO);

            // 
            organizations = organizationService.findByKaisoBango(Constants.DEFAULT_KAISOBANGO);
        } catch (IllegalArgumentException | ObjectNotFoundException ex) {
            logger.warn(ex.getMessage());

            // 
            organizations = Collections.emptyList();
        } catch (ServiceException ex) {
            logger.error(ex.getMessage(), ex);

            // ???????????
            model.addAttribute(ERROR, Boolean.TRUE);
            model.addAttribute(ERROR_MESSAGE, getSystemError());
            return getViewName();
        }
        model.addAttribute(PROCESSING_MONTH, DateUtil.monthsToSubtract(businessDay, 1));
        model.addAttribute(ORGNIZATIONS, organizations);

        // 
        logger.info("Successfully rendered the Jisekim view for logged-in user {} and organization {}",
                userOrgCode);
        return getViewName();
    }

    /**
     * Default mapping without path variables for Jisekim report screen
     * 
     * @param businessDay
     * @param proGNo
     * @param selectedCode
     * @return String redirect Uri
     */
    @RequestMapping(value = "/{selectedCode:[a-z0-9]+}", method = RequestMethod.GET)
    public String render(@SessionAttribute(Constants.SESS_BUSINESS_DAY) Date businessDay,
            @PathVariable String proGNo, @PathVariable String selectedCode) {
        if (logger.isDebugEnabled()) {
            logger.debug("Redering Jisekim report ...");
        }

        // Automatically build a redirect link
        UriComponents uriComponents = UriComponentsBuilder
                .fromUriString(Constants.JISEKIM_PATH + "/{selectedCode}/{monthly}").build();
        String businessMonth = DateFormatUtil.format(businessDay, DateFormat.DATE_WITHOUT_DAY);
        URI uri = uriComponents.expand(proGNo, selectedCode, businessMonth).encode().toUri();
        return "redirect:" + uri.toString();
    }

    /**
     * This function will be mapped with URL {@link /jisekim/ selectedCode}
     * /{monthly}, it can be used to render the Jisekim screen with a month for
     * a orgnization is selected. Will be displayed a message when have a
     * exception or an error occurred
     * 
     * @param userOrgCode
     * @param businessDay
     * @param selectedCode
     * @param monthly
     * @param model
     * @return String redirect Uri
     */
    @RequestMapping(value = "/{selectedCode:[a-z0-9]+}/{monthly:[\\d]+}", method = RequestMethod.GET)
    public String render(@SessionAttribute(Constants.SESS_ORGANIZATION_CODE) String userOrgCode,
            @SessionAttribute(Constants.SESS_BUSINESS_DAY) Date businessDay, @PathVariable String selectedCode,
            @PathVariable @DateTimeFormat(pattern = "yyyyMM") Date monthly, final Model model) {
        if (logger.isDebugEnabled()) {
            logger.debug("Redering Jisekim page...");
        }

        //
        model.addAttribute(SELECTED_ORG_CODE, selectedCode);
        model.addAttribute(PROCESSING_MONTH, monthly);

        // 
        logger.info("Trying to generate the Jisekim template for monthly {} and organization code {}", monthly,
                selectedCode);

        // Check allow edit current data or not
        boolean isEditable = Boolean.FALSE;

        try {
            String monthlyStr = DateFormatUtil.format(monthly, DateFormat.DATE_WITHOUT_DAY);
            // Get monthly Sales data by selected code, monthly and ugKbn = "1"
            List<ActualViewBean> salesBeansB = monthlySalesService.findDataBeansByOrgCodeAndMonthly(selectedCode,
                    monthlyStr, "1");
            if (CollectionUtils.isNotEmpty(salesBeansB)) {
                isEditable = Boolean.TRUE;
                Collections.sort(salesBeansB);
            }
            model.addAttribute(SALES_BEANS_B, salesBeansB);

            // Get monthly Sales data by selected code, monthly and ugKbn = "2"
            List<ActualViewBean> salesBeansC = monthlySalesService.findDataBeansByOrgCodeAndMonthly(selectedCode,
                    monthlyStr, "2");
            if (CollectionUtils.isNotEmpty(salesBeansC)) {
                isEditable = Boolean.TRUE;
                Collections.sort(salesBeansC);
            }
            model.addAttribute(SALES_BEANS_C, salesBeansC);

            // Get purchase Service data by selected code, monthly and bunruiKbn = "30"
            List<ActualViewBean> purchaseData30 = purchaseService.findDataBeansByOrgCodeAndMonthly(selectedCode,
                    monthlyStr, "30");
            if (CollectionUtils.isNotEmpty(purchaseData30)) {
                isEditable = Boolean.TRUE;
                Collections.sort(purchaseData30);
            }
            model.addAttribute(PURCHASES_DATA_30, purchaseData30);

            // Get purchase Service data by selected code, monthly and bunruiKbn = "60"
            List<ActualViewBean> purchaseData60 = purchaseService.findDataBeansByOrgCodeAndMonthly(selectedCode,
                    monthlyStr, "60");
            if (CollectionUtils.isNotEmpty(purchaseData60)) {
                isEditable = Boolean.TRUE;
                Collections.sort(purchaseData60);
            }
            model.addAttribute(PURCHASES_DATA_60, purchaseData60);

            // Get purchase Service data by selected code and monthly
            List<ActualViewBean> inventoryData = inventoryService.findDataBeansByOrgCodeAndMonthly(selectedCode,
                    monthlyStr);
            if (CollectionUtils.isNotEmpty(inventoryData)) {
                isEditable = Boolean.TRUE;
                Collections.sort(inventoryData);
            }
            model.addAttribute(INVENTORY_DATA, inventoryData);

            //
            ActualViewABean actualViewA = actualViewService.findActualViewAByOrgCodeAndMonth(selectedCode, monthly);
            model.addAttribute(ACTUAL_VIEW_A, actualViewA);
        } catch (IllegalArgumentException | ObjectNotFoundException ex) {
            logger.warn(ex.getMessage());
        } catch (ServiceException ex) {
            logger.error(ex.getMessage(), ex);

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

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

        try {
            tighten = tightenService.findByClassifyAndMonth("1"); // NOTE: fixed value is 1

            try {
                monthlyOfTighten = DateFormatUtil.parse(tighten.getGetSudo(), DateFormat.DATE_WITHOUT_DAY);
                isEditable = isEditable && monthly.after(monthlyOfTighten);
            } catch (NullPointerException | IllegalArgumentException | ParseException ex) {
                logger.warn(ex.getMessage());

                isEditable = Boolean.FALSE;
            }
        } catch (IllegalArgumentException | ObjectNotFoundException ex) {
            logger.warn(ex.getMessage());

        } catch (TooManyObjectsException ex) {
            logger.warn(ex.getMessage());

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

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

        if (monthlyOfTighten == null) {
            monthlyOfTighten = DateUtil.monthsToSubtract(businessDay, 3);
            if (isEditable) {
                isEditable = monthly.after(monthlyOfTighten);
            }
        }

        String previousMonthly = null;
        if (monthly.after(DateUtil.monthsToSubtract(monthlyOfTighten, -1))) {
            previousMonthly = BusinessDayHelper.getPreviousMonthly(monthly, DateFormat.DATE_WITHOUT_DAY);
        }

        // ??????????
        String nextMonthly = BusinessDayHelper.getNextMonthly(monthly, DateFormat.DATE_WITHOUT_DAY);

        //
        Date tempNextMontly = null;
        try {
            tempNextMontly = DateFormatUtil.parse(nextMonthly, DateFormat.DATE_WITHOUT_DAY);
        } catch (NullPointerException | IllegalArgumentException | ParseException ex) {
            logger.warn(ex.getMessage());
        }

        if (tempNextMontly == null || tempNextMontly.after(DateUtil.monthsToSubtract(businessDay, 1))) {
            nextMonthly = null;
        }

        model.addAttribute(PREVIOUS_MONTH, previousMonthly);
        model.addAttribute(NEXT_MONTH, nextMonthly);

        // Get list Organization for select box
        List<Organization> organizations;

        try {
            logger.info("Trying to get a list of organization for the given kaisobango {}",
                    Constants.DEFAULT_KAISOBANGO);

            // 
            organizations = organizationService.findByKaisoBango(Constants.DEFAULT_KAISOBANGO);
        } catch (IllegalArgumentException | ObjectNotFoundException ex) {
            logger.warn(ex.getMessage());

            // 
            organizations = Collections.emptyList();
        } catch (ServiceException ex) {
            logger.error(ex.getMessage(), ex);

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

        // 
        model.addAttribute(ORGNIZATIONS, organizations);
        // 
        if (isEditable) {
            isEditable = !monthly.after(DateUtil.monthsToSubtract(businessDay, 1));
        }
        model.addAttribute(EDITABLE, isEditable);
        logger.info("Successfully rendered the Jisekim view for logged-in user {} and organization {}",
                userOrgCode);
        return getViewName();
    }

    /**
     * This function will be mapped with URL {@link /jisekim/save/ selectedCode}
     * /{businessDay}}, it can be used to save jisekim data changed. Will be
     * displayed a message when have a exception or an error occurred.
     * 
     * @param selectedCode
     * @param monthly
     * @param model
     * @return JSonBean
     */
    @RequestMapping(value = "/save/{selectedCode:[a-z0-9]+}/{monthly:[\\d]+}", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody JSONBean saveJisekimData(@PathVariable String selectedCode,
            @PathVariable @MaskFormat("######") String monthly,
            @RequestBody final JSONListActualViewBean jSONListActualViewBean) {
        if (logger.isDebugEnabled()) {
            logger.debug(" Start updating data from Jisekim screen on month: " + monthly + " of organizetion code: "
                    + selectedCode);
        }

        try {
            boolean isSuccessful = handleUpdateJisekimData(selectedCode, monthly, jSONListActualViewBean);
            if (isSuccessful) {
                logger.info("Update Jisekim data is successful");

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

            //
            logger.warn("Update Jisekim data is not successful because updNo out of date");
            return new JSONBean(Boolean.FALSE, 2, MessageHelper.get(MsgConstants.CM_UPD_M01));
        } catch (IllegalArgumentException ex) {
            logger.warn(ex.getMessage());

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

            // 
            return new JSONBean(Boolean.FALSE, -1, MessageHelper.getSystemError());
        }
    }

    /**
     * Thit is function handle updating data from Jisekim screen
     * 
     * @param orgCode
     * @param monthly
     * @param jSONListActualView
     * @return boolean status update
     * @throws ServiceException
     */
    public boolean handleUpdateJisekimData(String orgCode, String monthly,
            JSONListActualViewBean jSONListActualView) throws ServiceException {
        if (StringUtils.isEmpty(orgCode)) {
            throw new IllegalArgumentException("Orginazation's code must not be null or empty");
        }

        if (StringUtils.isEmpty(monthly)) {
            throw new IllegalArgumentException("Month must not be null or empty");
        }

        if (jSONListActualView == null) {
            throw new IllegalArgumentException("Jisekim Beans object must not be null");
        }

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

        try {
            // 
            tx = session.beginTransaction();
            JSONActualViewBean[] salesBeans = jSONListActualView.getSalesBeans();
            if (ArrayUtils.isNotEmpty(salesBeans)) {
                boolean isUpdatedMonthlySale = monthlySalesService.updateSalesData(session, orgCode, monthly,
                        salesBeans);
                if (!isUpdatedMonthlySale) {
                    if (tx != null) {
                        tx.rollback();
                    }

                    // An error occurred while trying to update sale on month {} for organization {}
                    logger.error("An error occurred while trying to update sale on month " + monthly
                            + " for organization " + orgCode);
                    return false;
                }
            }

            JSONActualViewBean[] purchaseBeans = jSONListActualView.getPurchaseBeans();
            if (ArrayUtils.isNotEmpty(purchaseBeans)) {
                boolean isUpdatedPurchase = purchaseService.updatePurchaseData(session, orgCode, monthly,
                        purchaseBeans);
                if (!isUpdatedPurchase) {
                    if (tx != null) {
                        tx.rollback();
                    }

                    // An error occurred while trying to update sale on month {} for organization {}
                    logger.error("An error occurred while trying to update purchas on month " + monthly
                            + " for organization " + orgCode);
                    return false;
                }
            }

            JSONActualViewBean[] inventoryBeans = jSONListActualView.getInventoryBeans();
            if (ArrayUtils.isNotEmpty(inventoryBeans)) {
                boolean isUpdatedInventory = inventoryService.updateInventoryData(session, orgCode, monthly,
                        inventoryBeans);
                if (!isUpdatedInventory) {
                    if (tx != null) {
                        tx.rollback();
                    }

                    // 
                    logger.error("An error occurred while trying to update inventory on month " + monthly
                            + " for organization " + orgCode);
                    return false;
                }
            }
            tx.commit();
            return true;
        } catch (SQLGrammarException ex) {
            if (tx != null) {
                tx.rollback();
            }
            throw new ServiceException("An error occurred while update Jisekim Datas", ex);
        } finally {
            // ?
            HibernateSessionManager.closeSession(session);
        }
    }

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

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

}