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

Java tutorial

Introduction

Here is the source code for com.nec.harvest.controller.UriageController.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.io.IOException;
import java.net.URI;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ArrayUtils;
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.harvest.bean.mapping.SalesChangeBean;
import com.nec.harvest.bean.mapping.json.JSONBean;
import com.nec.harvest.bean.mapping.json.JSONSales;
import com.nec.harvest.bean.mapping.json.JSONSalesChange;
import com.nec.harvest.bean.mapping.json.JSONSalesFixed;
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.helper.ProductHelper;
import com.nec.harvest.menu.group.DailyReportingProGroup;
import com.nec.harvest.model.Organization;
import com.nec.harvest.model.SalesChange;
import com.nec.harvest.model.SalesFixed;
import com.nec.harvest.model.Tighten;
import com.nec.harvest.model.User;
import com.nec.harvest.service.ConsumptionTaxRateService;
import com.nec.harvest.service.MonthlySalesService;
import com.nec.harvest.service.OrganizationService;
import com.nec.harvest.service.SalesChangeService;
import com.nec.harvest.service.SalesFixedService;
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 sales report
 * screen
 * 
 * @author QuanDK
 * 
 */
@Controller
@RequestMapping(value = Constants.URIAGE_PATH)
public class UriageController extends DailyReportingProGroup implements AbstractRenderer, TitleRenderer {

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

    private static final String SALES_CHANGE_CATEGORY = "salesChanges";
    private static final String SALES_FIXED = "salesFixed";
    private static final String TAX_TYPE = "taxKbn";
    private static final String COUNT_DATE = "countDate";
    private static final String FORMAT_DATE = "dd/MM/yyyy";

    private final SalesChangeService salesChangeService;

    private final SalesFixedService salesFixedService;

    private final TightenService tightenService;

    private final ConsumptionTaxRateService consumptionTaxRateService;

    private final MonthlySalesService monthlySalesService;

    private final OrganizationService organizationService;

    @Inject
    public UriageController(SalesFixedService salesFixedService, SalesChangeService salesChangeService,
            TightenService tightenService, ConsumptionTaxRateService consumptionTaxRateService,
            MonthlySalesService monthlySalesService, OrganizationService organizationService) {
        this.salesChangeService = salesChangeService;
        this.salesFixedService = salesFixedService;
        this.tightenService = tightenService;
        this.monthlySalesService = monthlySalesService;
        this.consumptionTaxRateService = consumptionTaxRateService;
        this.organizationService = organizationService;
    }

    /**
     * Default mapping without path variables for Sales report screen
     * 
     * @param request
     * @param response
     * @param model
     * @param orgCode
     * @param businessDay
     * @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) {
        if (logger.isDebugEnabled()) {
            logger.debug("Redering uriage report without parameters...");
        }

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

    /**
     * This function will be mapped with URL {@link /uriage/ organizationCode}
     * /{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 orgCodeStored
     * @param businessDay
     * @param orgCode
     * @param monthly
     * @param request
     * @param model
     * @return String redirect Uri
     */
    @RequestMapping("/{orgCode:[a-z0-9]+}/{monthly:[\\d]+}")
    public String render(@SessionAttribute(Constants.SESS_BUSINESS_DAY) Date businessDay, @UserPrincipal User user,
            @PathVariable String proGNo, @PathVariable String orgCode,
            @PathVariable @DateTimeFormat(pattern = "yyyyMM") Date monthly, final Model model) {
        if (logger.isDebugEnabled()) {
            logger.debug("Redering uriage page...");
        }

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

        String monthlyStr = null;
        try {
            monthlyStr = DateFormatUtil.format(monthly, DateFormat.DATE_WITHOUT_DAY);
            model.addAttribute(PROCESSING_MONTH, monthly);
        } catch (NullPointerException | IllegalArgumentException ex) {
            logger.warn(ex.getMessage());
        }

        // ????
        Organization organization = user.getOrganization();
        if (organization != null) {
            // ????1???""?2???""??
            logger.info(
                    "????1???\"\"?2???\"\"??");
            //
            organization = organizationService.findByOrgCode(organization.getStrCode());

            // 
            model.addAttribute(TAX_TYPE, organization.getTaxKbn());
            model.addAttribute(COUNT_DATE, getActualMaximumDayOfMonth(monthly));
            model.addAttribute(ORGANIZATION, organization);
        }

        // Get a list of UriageData(Hendo)/at001 data from DB
        List<SalesChange> salesChanges = null;

        try {
            salesChanges = salesChangeService.findByOrgCodeAndMonth(orgCode, monthlyStr, false);
        } catch (IllegalArgumentException | ObjectNotFoundException ex) {
            logger.warn(ex.getMessage());

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

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

        try {
            String nextMontly = BusinessDayHelper.getNextMonthly(monthly, DateFormat.DATE_WITHOUT_DAY);
            boolean checkEmptyMonthly = hasSaleChangesOfMonthly(orgCode, nextMontly);

            // Disable the "NEXT MONTHLY" button if the data of next month is empty or null
            if (!checkEmptyMonthly) {
                nextMontly = null;
            }

            model.addAttribute(NEXT_MONTH, nextMontly);

            String previousMonthly = BusinessDayHelper.getPreviousMonthly(monthly, DateFormat.DATE_WITHOUT_DAY);
            checkEmptyMonthly = hasSaleChangesOfMonthly(orgCode, previousMonthly);

            // Disable the "PREVIOUS MONTHLY" button if the data of previous month is empty or null
            if (!checkEmptyMonthly) {
                previousMonthly = null;
            }
            model.addAttribute(PREVIOUS_MONTH, previousMonthly);
        } catch (ServiceException ex) {
            logger.error(ex.getMessage());

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

        List<SalesChangeBean> salesChangeBeans = new ArrayList<>();
        if (CollectionUtils.isEmpty(salesChanges)) {
            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(SALES_CHANGE_CATEGORY, salesChangeBeans);
            return getViewName();
        }

        try {
            Map<String, Double> rateDefMap = consumptionTaxRateService.findRateDefByMonth(monthly);
            Object[] keySet = rateDefMap.keySet().toArray();
            Double taxRateTmp = 0D;
            String enfDateStrTmp = null;

            String keyStr = null;
            for (SalesChange obj : salesChanges) {
                for (int i = 0; i < keySet.length; i++) {
                    keyStr = keySet[i].toString();
                    Date actualDate = obj.getSrDate();
                    try {
                        Date date = DateFormatUtil.parse(keyStr, FORMAT_DATE);
                        if (!actualDate.before(date)) {
                            //get taxRate with folowed date
                            if (enfDateStrTmp == null
                                    || !date.before(DateFormatUtil.parse(enfDateStrTmp, FORMAT_DATE))) {
                                enfDateStrTmp = keyStr;
                                taxRateTmp = rateDefMap.get(keyStr);
                            }
                            keySet = ArrayUtils.removeElement(keySet, keySet[i]);
                            i--;
                        }
                    } catch (NullPointerException | ParseException e) {
                        logger.warn("warning parse string to date is error: " + e.getMessage());
                        continue;
                    }
                }
                SalesChangeBean bean = new SalesChangeBean(taxRateTmp, obj);
                salesChangeBeans.add(bean);
            }
        } catch (IllegalArgumentException ex) {
            logger.warn(ex.getMessage());

            model.addAttribute(ERROR, true);
            model.addAttribute(ERROR_MESSAGE, MessageHelper.get(MsgConstants.CM_QRY_M01));
            return getViewName();
        } catch (ServiceException ex) {
            logger.error(ex.getMessage(), ex);

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

        model.addAttribute(SALES_CHANGE_CATEGORY, salesChangeBeans);

        try {
            SalesFixed salesFixedObj = salesFixedService.findByOrgCodeAndMonth(orgCode, monthlyStr, false);
            model.addAttribute(SALES_FIXED, salesFixedObj);
        } catch (IllegalArgumentException ex) {
            logger.warn(ex.getMessage());

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

            // ???????????
            model.addAttribute(ERROR_MESSAGE, getSystemError());
            model.addAttribute(ERROR, 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;

        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 sales 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 URL {@link /uriage/save/{organizationCode}
     * /{businessDay}}, it can be used to save sales data changed. 
     * Will be displayed a message when have a exception or an error
     * occurred.
     * @param orgCode
     * @param monthly
     * @param params
     * @param model
     * @return JSonBean
     */
    @RequestMapping(value = "/save/{orgCode:[a-z0-9]+}/{monthly:[\\d]+}", method = RequestMethod.POST, consumes = "application/json")
    public @ResponseBody JSONBean saveUriageData(@UserPrincipal User user, @PathVariable String proGNo,
            @PathVariable String orgCode, @PathVariable @MaskFormat("######") String monthly,
            @RequestBody final JSONSales jSONSales, final Model model) {
        if (logger.isDebugEnabled()) {
            logger.debug("Saving sales data on month: " + monthly + " of organizetion code: " + orgCode);
        }

        String version = "";
        try {
            version = ProductHelper.getProductInfor().getVersion();
        } catch (IOException ex) {
            logger.warn(ex.getMessage());
        }

        List<SalesChange> salesChanges = null;
        try {
            salesChanges = (List<SalesChange>) salesChangeService.findByOrgCodeAndMonth(orgCode, monthly, true);
        } catch (IllegalArgumentException | ObjectNotFoundException ex) {
            logger.warn(ex.getMessage());

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

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

        String userCode = user.getUsrCode();
        List<SalesChange> salesChangeUpdLst = new ArrayList<SalesChange>();
        JSONSalesChange[] salesChangeUpds = jSONSales.getSalesChangeDatas();
        boolean isUpdated = false;
        Date curDate = new Date();
        Calendar calendar = GregorianCalendar.getInstance();
        calendar.setTime(curDate);
        for (int i = 0; i < salesChanges.size(); i++) {
            SalesChange salesChange = salesChanges.get(i);
            JSONSalesChange salesChangeUpd = salesChangeUpds[i];
            Integer updNoOld = salesChangeUpd.getUpdNo();
            Integer updNoNew = salesChange.getUpdNo();
            if (updNoOld == null && updNoNew == null) {
                isUpdated = true;
                updNoNew = 0;
            } else if (updNoOld.equals(updNoNew)) {
                isUpdated = true;
            } else {
                isUpdated = false;
            }
            if (isUpdated) {
                salesChange
                        .setGenkinUri(salesChangeUpd.getGenkinUri() != null ? salesChangeUpd.getGenkinUri() : 0D);
                salesChange.setZatsuUri(salesChangeUpd.getZatsuUri() != null ? salesChangeUpd.getZatsuUri() : 0D);
                salesChange.setKaisyuKG(salesChangeUpd.getKaisyuKG() != null ? salesChangeUpd.getKaisyuKG() : 0D);
                salesChange.setRem(salesChangeUpd.getRem());
                salesChange.setUriageKeijo1(
                        salesChangeUpd.getUriageKeijo1() != null ? salesChangeUpd.getUriageKeijo1() : 0D);
                salesChange.setUriageKeijo2(
                        salesChangeUpd.getUriageKeijo2() != null ? salesChangeUpd.getUriageKeijo2() : 0D);
                salesChange.setUriageKeijo3(
                        salesChangeUpd.getUriageKeijo3() != null ? salesChangeUpd.getUriageKeijo3() : 0D);
                salesChange.setShokenUrikake(
                        salesChangeUpd.getShokenUrikake() != null ? salesChangeUpd.getShokenUrikake() : 0D);
                salesChange.setUpdNo(updNoNew + 1);
                salesChange.setTanCode(userCode);
                salesChange.setAPInf2(userCode);
                salesChange.setStfCodeU(userCode);
                salesChange.setPrdNoU(version);
                salesChange.setTimeU(calendar);
                salesChangeUpdLst.add(salesChange);
            } else {
                return new JSONBean(Boolean.FALSE, "", MessageHelper.get(MsgConstants.CM_UPD_M01));
            }
        }

        boolean actualUpdateState = salesChangeService.updateSalesChanges(salesChanges);
        if (!actualUpdateState) {
            return new JSONBean(Boolean.FALSE, "", MessageHelper.get(MsgConstants.CM_UPD_M03));
        }

        SalesFixed salesFixedObj = salesFixedService.findByOrgCodeAndMonth(orgCode, monthly, true);
        if (salesFixedObj != null) {
            JSONSalesFixed salesFixedUpd = jSONSales.getSalesFixedData();
            Integer updNoOld = salesFixedObj.getUpdNo();
            Integer updNoNew = salesFixedUpd.getUpdNo();
            if (updNoOld == null && updNoNew == null) {
                isUpdated = true;
                updNoNew = 0;
            } else if (updNoOld.equals(updNoNew)) {
                isUpdated = true;
            } else {
                isUpdated = false;
            }
            if (isUpdated) {
                salesFixedObj.setKanrihi1(salesFixedUpd.getKanrihi1() != null ? salesFixedUpd.getKanrihi1() : 0D);
                salesFixedObj.setKanrihi2(salesFixedUpd.getKanrihi2() != null ? salesFixedUpd.getKanrihi2() : 0D);
                salesFixedObj.setKanrihi3(salesFixedUpd.getKanrihi3() != null ? salesFixedUpd.getKanrihi3() : 0D);
                salesFixedObj.setUrikakeSosai1(
                        salesFixedUpd.getUrikakeSosai1() != null ? salesFixedUpd.getUrikakeSosai1() : 0D);
                salesFixedObj.setUrikakeSosai2(
                        salesFixedUpd.getUrikakeSosai2() != null ? salesFixedUpd.getUrikakeSosai2() : 0D);
                salesFixedObj.setUrikakeSosai3(
                        salesFixedUpd.getUrikakeSosai3() != null ? salesFixedUpd.getUrikakeSosai3() : 0D);
                salesFixedObj.setUpdNo(updNoNew + 1);
                salesFixedObj.setTanCode(userCode);
                salesFixedObj.setAPInf2(userCode);
                salesFixedObj.setStfCodeU(userCode);
                salesFixedObj.setPrdNoU(version);
                salesFixedObj.setTimeU(calendar);
                salesFixedObj.setUpdID(curDate);
            } else {
                return new JSONBean(Boolean.FALSE, "", MessageHelper.get(MsgConstants.CM_UPD_M01));
            }

            actualUpdateState = salesFixedService.updateSalesFixeds(salesFixedObj);
            if (!actualUpdateState) {
                return new JSONBean(Boolean.FALSE, "", MessageHelper.get(MsgConstants.CM_UPD_M03));
            }
        }
        return new JSONBean(true, "", MessageHelper.get(MsgConstants.CM_UPD_M02));
    }

    /**
     * Check Sales Data AT031
     * 
     * @param orgCode
     * @param monthly
     * @param params
     * @param model
     * @return JsonBean
     */
    @RequestMapping(value = "/check/{orgCode:[a-z0-9]+}/{monthly:[\\d]+}", method = RequestMethod.GET)
    public @ResponseBody JSONBean checkSalesDataMonthly(@PathVariable String proGNo, @PathVariable String orgCode,
            @PathVariable @DateTimeFormat(pattern = "yyyyMM") Date monthly) {
        String processMonthly = DateFormatUtil.format(monthly, DateFormat.DATE_WITHOUT_DAY);
        logger.debug("Checking sales data on month: " + processMonthly + " of organizetion code: " + orgCode);
        if (logger.isDebugEnabled()) {
            logger.debug("Checking sales data on month: " + processMonthly + " of organizetion code: " + orgCode);
        }

        try {
            int saleDataOfMonthly = monthlySalesService.findByOrgCodeAndMonth(orgCode, processMonthly, 1);
            if (saleDataOfMonthly > 0) {
                return new JSONBean(Boolean.TRUE, "", MessageHelper.get(MsgConstants.CM_CFM_REG_M02));
            } else {
                return new JSONBean(Boolean.TRUE, "", MessageHelper.get(MsgConstants.CM_CFM_REG_M01));
            }
        } catch (IllegalArgumentException ex) {
            logger.warn(ex.getMessage());

        } catch (ServiceException ex) {
            logger.error(ex.getMessage(), ex);
        }
        return new JSONBean(Boolean.FALSE, "", getSystemError());
    }

    /**
     * Check empty SalesChange values in month.
     * 
     * @param strCode
     * @param getsudo
     * @return TRUE if sales change data on month is empty, FALSE if not empty
     * @throws IllegalArgumentException
     */
    protected boolean hasSaleChangesOfMonthly(String strCode, String getsudo) {
        if (logger.isDebugEnabled()) {
            logger.debug("Checking empty sales data on month: " + getsudo + " of organizetion code: " + strCode);
        }

        try {
            Long hasNextMontly = salesChangeService.countByOrgCodeAndMonth(strCode, getsudo);
            return (hasNextMontly > 0);
        } catch (IllegalArgumentException ex) {
            logger.warn(ex.getMessage());

        } catch (ServiceException ex) {
            throw new ServiceException(ex.getMessage());
        }
        return false;
    }

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

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

}