package kcg.faics.report.web;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import kcg.faics.cmmn.excel.ExcelExporter;
import kcg.faics.cmmn.service.CodeService;
import kcg.faics.member.UserType;
import kcg.faics.member.service.MemberService;
import kcg.faics.member.vo.MemberVO;
import kcg.faics.report.service.ReportCategoryService;
import kcg.faics.report.service.ReportJudgeService;
import kcg.faics.report.service.ReportService;
import kcg.faics.report.vo.ReportGoalVO;
import kcg.faics.report.vo.ReportSearchVO;
import kcg.faics.report.vo.ReportVO;
import kcg.faics.sec.LoginUserVO;
import kcg.faics.sec.UserUtil;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springmodules.validation.commons.DefaultBeanValidator;

import egovframework.rte.fdl.property.EgovPropertyService;
import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper;
import egovframework.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
/**
 * @author 하영지
 * 견문 관리기능 메뉴 컨트롤러
 */
@Controller
@RequestMapping("/report")
public class ReportMngController {
	/**
	 * properties값을 가져오는 인터페이스.
	 **/
	@Resource(name = "propertiesService")
	private EgovPropertyService propertiesService;
	
	/**
	 * 견문 기본 인터페이스이다. 
	 */
	@Resource(name = "reportService")
	private ReportService reportService;

	/**
	 * 견문 결재 인터페이스 
	 */
	@Resource(name = "reportJudgeService")
	private ReportJudgeService judgeService;
	
	/**
	 * 사용자 인터페이스
	 */
	@Resource(name = "memberService")
	private MemberService memberService;
	
	/**
	 * Validator - 유효성 검사
	 **/
	@Resource(name = "beanValidator")
	private DefaultBeanValidator beanValidator;

	/**
	 * 코드 인터페이스
	 */
	@Resource(name = "codeService")
	private CodeService codeService;

	/**
	 * 견문 분류 인터페이스
	 */
	@Resource(name = "reportCategoryService")
	private ReportCategoryService cateService;
	
	/**
	 * message.properties의 값을 가져오는 인터페이스.
	 */
	@Autowired
	private MessageSource messageSource;

	/**
	 * 견문제출현황을 반환한다.
	 * 
	 * @param reportSearchVO 견문 검색 객체
	 * @param model 모델 객체
	 * @param request 리퀘스트 객체
	 * @param status 세션 객체
	 * @return 견문제출현황 화면
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping(value = "presentList.do")
	public String presentList(@ModelAttribute final ReportSearchVO reportSearchVO, final Model model,
			final HttpServletRequest request, final SessionStatus status) throws Exception {		
		try {
			// 기간 설정
			Calendar cal = new GregorianCalendar();
			SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
			if (StringUtils.isBlank(reportSearchVO.getDateStart())) {
				cal.add(Calendar.YEAR, -1);
				reportSearchVO.setDateStart(dateFormatter.format(cal.getTime()));
			}
			if (StringUtils.isBlank(reportSearchVO.getDateEnd())) {
				cal = new GregorianCalendar();
				reportSearchVO.setDateEnd(dateFormatter.format(cal.getTime()));
			}
			
			// 접속한 사용자 정보
			model.addAttribute("myGroupCode", ReportCommon.getMyGroupCode());
			model.addAttribute("myDutiesCode", UserUtil.getMemberInfo().getDuties());

			/* 페이징 처리 정보 */
			reportSearchVO.setPageUnit(propertiesService.getInt("pageUnit"));
			reportSearchVO.setPageSize(propertiesService.getInt("pageSize"));
			
			/* 페이징 처리 */
			PaginationInfo paginationInfo = new PaginationInfo();
			paginationInfo.setCurrentPageNo(reportSearchVO.getPageIndex());
			paginationInfo.setRecordCountPerPage(15);
			paginationInfo.setPageSize(reportSearchVO.getPageSize());

			reportSearchVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
			reportSearchVO.setLastIndex(paginationInfo.getLastRecordIndex());
			reportSearchVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
			
			ReportSearchVO vo = ReportCommon.setSearchUserInfo(reportSearchVO); 
			// 전체 갯수 설정
			int totSearchCnt = reportService.selectPresentListCnt(vo);
			paginationInfo.setTotalRecordCount(totSearchCnt);
			model.addAttribute("paginationInfo", paginationInfo);
			model.addAttribute("totalCnt", totSearchCnt);

			List<ReportVO> reportList = reportService.selectPresentList(vo);
			model.addAttribute("reportList", reportList);
			
			// 검색 조건
			model.addAttribute("reportSearchVO", vo);
			// 평가 목록
			model.addAttribute("judgeList", judgeService.judgeList());
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "report/presentList.tiles";
	}

	/**
	 * 견문제출현황 엑셀문서를 반환한다.
	 * 
	 * @param reportSearchVO 견문 검색 객체
	 * @param model 모델 객체
	 * @param locale locale 객체
	 * @return 견문제출현황 화면
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping(value = "presentExcel")
	public String presentExcel(@ModelAttribute final ReportSearchVO reportSearchVO, final Model model, final Locale locale) throws Exception {		
		LinkedHashMap<String, String> header = new LinkedHashMap<String, String>();
		header.put("docNo", messageSource.getMessage("report.list.num", null, locale));
		header.put("reporter", messageSource.getMessage("report.search.reporter", null, locale));
		header.put("cateStrOrder", messageSource.getMessage("report.view.category", null, locale));
		header.put("inSubject", messageSource.getMessage("board.header.title", null, locale));
		header.put("inInfodate", messageSource.getMessage("report.view.infodate", null, locale));
		header.put("isHead", messageSource.getMessage("report.view.approval", null, locale) 
				+ messageSource.getMessage("member.view.rptPermission.head", null, locale));
		header.put("isSection", messageSource.getMessage("report.view.approval", null, locale) 
				+ messageSource.getMessage("member.view.rptPermission.section", null, locale));
		header.put("isJudge1", messageSource.getMessage("report.type.newsflash", null, locale));
		header.put("isJudge2", messageSource.getMessage("report.type.judge", null, locale));
		header.put("isJudge3", messageSource.getMessage("report.type.middle", null, locale));
		header.put("isJudge4", messageSource.getMessage("report.type.notice", null, locale));
		header.put("isJudge5", messageSource.getMessage("report.type.record", null, locale));
		header.put("isJudge6", messageSource.getMessage("report.type.survey", null, locale));
		header.put("isJudge7", messageSource.getMessage("report.type.reference", null, locale));
		header.put("isReport1", messageSource.getMessage("report.type.fullReport1", null, locale) 
				+ messageSource.getMessage("report.type.fullReport", null, locale));
		header.put("isReport2", messageSource.getMessage("report.type.fullReport2", null, locale) 
				+ messageSource.getMessage("report.type.fullReport", null, locale));
		
		try {
			Date d = new Date();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
			String title = String.format("%s_%s", messageSource.getMessage("report.title", null, locale), sdf.format(d));
			
			List<ReportVO> list = reportService.selectPresentListAll(ReportCommon.setSearchUserInfo(reportSearchVO));
			
			model.addAttribute("excel", new ExcelExporter<ReportVO>(header, list, title));
			model.addAttribute("filename", title);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "excelView";
	}

	/**
	 * 목표 관리 화면을 반환한다.
	 * 
	 * @param reportSearchVO 견문 검색 객체
	 * @param model 모델객체
	 * @return 목표 관리
	 * @throws Exception 기본예외처리
	 */
	@RequestMapping(value = "/goal.do", method = RequestMethod.GET)
	public String goal(@ModelAttribute final ReportSearchVO reportSearchVO, final Model model) throws Exception {
		LoginUserVO loginUserVO = UserUtil.getMemberInfo();
		model.addAttribute("authAdmin", loginUserVO.getAuthAdmin());

		// 소속 목록
		model.addAttribute("placeList", codeService.getPlace1List(false));

		// 소속
		if (StringUtils.isBlank(reportSearchVO.getPlaceGroup())) {
			reportSearchVO.setPlaceGroup(loginUserVO.getPlace1());
		}

		Calendar c = Calendar.getInstance();
		int currYear = c.get(Calendar.YEAR);
		int currMonth = c.get(Calendar.MONTH) + 1;
		// 기간
		if (StringUtils.isBlank(reportSearchVO.getYear())) {
			reportSearchVO.setYear(String.valueOf(currYear));
			reportSearchVO.setMonth(String.valueOf(currMonth));
		}
		
		List<Integer> yearList = new ArrayList<Integer>();		
		for (int i = 2005; i <= currYear; i++) {
			yearList.add(i);
		}
		model.addAttribute("yearList", yearList);
		
		List<Integer> monthList = new ArrayList<Integer>();
		for (int i = 1; i <= 12; i++) {
			monthList.add(i);
		}
		model.addAttribute("monthList", monthList);
		
		// 목표 목록
		model.addAttribute("goalList", reportService.selectGoalList(reportSearchVO));

		model.addAttribute("reportSearchVO", reportSearchVO);
		model.addAttribute("reportGoalVO", new ReportGoalVO());
		return "report/goal.tiles";
	}

	/**
	 * 목표를 수정한다.
	 * 
	 * @param reportGoalVO 견문 목표 객체
	 * @param model 모델객체
	 * @return 목표 관리 목록
	 * @throws Exception 기본예외처리
	 */
	@RequestMapping(value = "/goal.do", method = RequestMethod.POST)
	public String goal(@ModelAttribute final ReportGoalVO reportGoalVO, final Model model) throws Exception {
		try {
			reportService.updateGoal(reportGoalVO);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "redirect:/report/goal.do";
	}

	/**
	 * 사용자별 목표/실적 조회 화면을 반환한다.
	 * 소속코드가 없으면 사용자의 소속 코드를 세팅한다.
	 * 
	 * @param reportSearchVO 견문 검색 객체
	 * @param model 모델 객체
	 * @return 목표/실적 조회 화면
	 * @throws Exception 기본예외처리
	 */
	@RequestMapping(value = "/goalStats.do")
	public String getStatsUser(@ModelAttribute final ReportSearchVO reportSearchVO, final Model model) throws Exception {
		if (StringUtils.isBlank(reportSearchVO.getPlaceGroup())) {
			reportSearchVO.setPlaceGroup(UserUtil.getMemberInfo().getPlace1());
		}
		
		return goalStats(reportSearchVO, model);
	}

	/**
	 * 소속별 목표/실적 조회 화면을 반환한다.
	 * 
	 * @param reportSearchVO 견문 검색 객체
	 * @param model 모델 객체
	 * @return 목표/실적 조회 화면
	 * @throws Exception 기본예외처리
	 */
	@RequestMapping(value = "/goalStatsPlace.do")
	public String getStatsPlace(@ModelAttribute final ReportSearchVO reportSearchVO, final Model model) throws Exception {
		reportSearchVO.setPlaceGroup(null);
		return goalStats(reportSearchVO, model);
	}
	
	/**
	 * 목표/실적 조회 화면을 반환한다.
	 * 
	 * @param reportSearchVO 견문 검색 객체
	 * @param model 모델 객체
	 * @return 목표/실적 조회 화면
	 * @throws Exception 기본예외처리
	 */
	public String goalStats(@ModelAttribute final ReportSearchVO reportSearchVO, final Model model) throws Exception {
		model.addAttribute("authAdmin", UserUtil.getMemberInfo().getAuthAdmin());
		
		// 소속 목록
		model.addAttribute("placeList", codeService.getPlace1List(false));
	
		Calendar c = Calendar.getInstance();
		int currYear = c.get(Calendar.YEAR);
		int currMonth = c.get(Calendar.MONTH) + 1;
		// 기간
		if (StringUtils.isBlank(reportSearchVO.getYear())) {
			reportSearchVO.setYear(String.valueOf(currYear));
			reportSearchVO.setMonth(String.valueOf(currMonth));
		}

		List<Integer> yearList = new ArrayList<Integer>();		
		for (int i = 2005; i <= currYear; i++) {
			yearList.add(i);
		}
		model.addAttribute("yearList", yearList);
		
		List<Integer> monthList = new ArrayList<Integer>();
		for (int i = 1; i <= 12; i++) {
			monthList.add(i);
		}
		model.addAttribute("monthList", monthList);

		// 목표/실적 통계
		if (StringUtils.isBlank(reportSearchVO.getPlaceGroup())) {
			model.addAttribute("goalStats", reportService.getGoalStatsPlace(reportSearchVO));
		} else {
			model.addAttribute("goalStats", reportService.getGoalStats(reportSearchVO));
		}
		
		model.addAttribute("reportSearchVO", reportSearchVO);
		
		return "report/goalStats.tiles";
	}

	/**
	 * 목표/실적 엑셀 문서를 반환한다.
	 * 
	 * @param reportSearchVO 견문 검색 객체
	 * @param model 모델 객체
	 * @param locale locale 객체
	 * @return 목표/실적 엑셀 문서
	 * @throws Exception 기본예외처리
	 */
	@RequestMapping(value = "/goalStatsExcel.do")
	public String goalStatsExcel(@ModelAttribute final ReportSearchVO reportSearchVO, final Model model, final Locale locale) throws Exception {
		LinkedHashMap<String, String> header = new LinkedHashMap<String, String>();
		header.put("NAME", messageSource.getMessage("report.goal.name", null, locale));
		header.put("RESULT1", messageSource.getMessage("report.goal.agent", null, locale)
				+ messageSource.getMessage("report.goal.result", null, locale));
		header.put("GOAL1", messageSource.getMessage("report.goal.agent", null, locale)
				+ messageSource.getMessage("report.goal.goal", null, locale));
		header.put("RESULT2", messageSource.getMessage("report.goal.foreignCoop", null, locale)
				+ messageSource.getMessage("report.goal.result", null, locale));
		header.put("GOAL2", messageSource.getMessage("report.goal.foreignCoop", null, locale)
				+ messageSource.getMessage("report.goal.goal", null, locale));
		header.put("RESULT3", messageSource.getMessage("report.goal.infoCoop", null, locale)
				+ messageSource.getMessage("report.goal.result", null, locale));
		header.put("GOAL3", messageSource.getMessage("report.goal.infoCoop", null, locale)
				+ messageSource.getMessage("report.goal.goal", null, locale));
		header.put("RESULT4", messageSource.getMessage("report.goal.reportAgent", null, locale)
				+ messageSource.getMessage("report.goal.result", null, locale));
		header.put("GOAL4", messageSource.getMessage("report.goal.reportAgent", null, locale)
				+ messageSource.getMessage("report.goal.goal", null, locale));
		header.put("RESULT_TOTAL", messageSource.getMessage("report.goal.sum", null, locale)
				+ messageSource.getMessage("report.goal.result", null, locale));
		header.put("GOAL_TOTAL", messageSource.getMessage("report.goal.sum", null, locale)
				+ messageSource.getMessage("report.goal.goal", null, locale));
	
		try {
			Date d = new Date();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
			String title = String.format("%s_%s", messageSource.getMessage("report.title", null, locale), sdf.format(d));
			
			List<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>(); 
			if (StringUtils.isBlank(reportSearchVO.getPlaceGroup())) {
				list = reportService.getGoalStatsPlace(reportSearchVO);
			} else {
				list = reportService.getGoalStats(reportSearchVO);
			}
			
			model.addAttribute("excel", new ExcelExporter<HashMap<String, Object>>(header, list, title));
			model.addAttribute("filename", title);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "excelView";
	}
	
	/**
	 * 평가기록부를 반환한다.
	 * 
	 * @param reportSearchVO 견문 검색 객체
	 * @param model 모델 객체
	 * @param request 리퀘스트 객체
	 * @param status 세션 객체
	 * @return 평가기록부 화면
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping(value = "judgeRecord.do")
	public String recordtList(@ModelAttribute final ReportSearchVO reportSearchVO, final Model model,
			final HttpServletRequest request, final SessionStatus status) throws Exception {		
		try {
			// 기간 설정
			Calendar cal = new GregorianCalendar();
			SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
			if (StringUtils.isBlank(reportSearchVO.getDateStart())) {
				cal.add(Calendar.YEAR, -1);
				reportSearchVO.setDateStart(dateFormatter.format(cal.getTime()));
			}
			if (StringUtils.isBlank(reportSearchVO.getDateEnd())) {
				cal = new GregorianCalendar();
				reportSearchVO.setDateEnd(dateFormatter.format(cal.getTime()));
			}
			
			// 소속 목록
			model.addAttribute("placeList", codeService.getPlace1List(false));
			
			LoginUserVO loginUserVO = UserUtil.getMemberInfo();
			
			// 검색 조건 소속
			if (StringUtils.isBlank(reportSearchVO.getPlaceGroup())) {
				reportSearchVO.setPlaceGroup(loginUserVO.getPlace1());
			}
			
			// 접속한 사용자 정보
			model.addAttribute("myGroupCode", ReportCommon.getMyGroupCode());
			model.addAttribute("myDutiesCode", loginUserVO.getDuties());

			/* 페이징 처리 정보 */
			reportSearchVO.setPageUnit(propertiesService.getInt("pageUnit"));
			reportSearchVO.setPageSize(propertiesService.getInt("pageSize"));
			
			/* 페이징 처리 */
			PaginationInfo paginationInfo = new PaginationInfo();
			paginationInfo.setCurrentPageNo(reportSearchVO.getPageIndex());
			paginationInfo.setRecordCountPerPage(15);
			paginationInfo.setPageSize(reportSearchVO.getPageSize());

			reportSearchVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
			reportSearchVO.setLastIndex(paginationInfo.getLastRecordIndex());
			reportSearchVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
			
			ReportSearchVO vo = ReportCommon.setSearchUserInfo(reportSearchVO); 
			// 전체 갯수 설정
			int totSearchCnt = reportService.selectRecordListCnt(vo);
			paginationInfo.setTotalRecordCount(totSearchCnt);
			model.addAttribute("paginationInfo", paginationInfo);
			model.addAttribute("totalCnt", totSearchCnt);

			List<ReportVO> reportList = reportService.selectRecordList(vo);
			model.addAttribute("reportList", reportList);
			
			// 검색 조건
			model.addAttribute("reportSearchVO", vo);
			// 평가 목록
			model.addAttribute("judgeList", judgeService.judgeList());
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "report/judgeRecord.tiles";
	}

	/**
	 * 평가기록부 엑셀문서를 반환한다.
	 * 
	 * @param reportSearchVO 견문 검색 객체
	 * @param model 모델 객체
	 * @param locale locale 객체
	 * @return 평가기록부 엑셀문서
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping(value = "recordExcel")
	public String recordExcel(@ModelAttribute final ReportSearchVO reportSearchVO, final Model model, final Locale locale) throws Exception {		
		LinkedHashMap<String, String> header = new LinkedHashMap<String, String>();
		header.put("docNo", messageSource.getMessage("report.list.num", null, locale));
		header.put("inInfodate", messageSource.getMessage("report.view.infodate", null, locale));
		header.put("inPosition", messageSource.getMessage("report.view.position", null, locale));
		header.put("inName", messageSource.getMessage("report.search.reporter", null, locale));
		header.put("inSubject", messageSource.getMessage("board.header.title", null, locale));
		header.put("isJudge1", messageSource.getMessage("report.type.newsflash", null, locale));
		header.put("isJudge2", messageSource.getMessage("report.type.judge", null, locale));
		header.put("isJudge3", messageSource.getMessage("report.type.middle", null, locale));
		header.put("isJudge4", messageSource.getMessage("report.type.notice", null, locale));
		header.put("isJudge5", messageSource.getMessage("report.type.record", null, locale));
		header.put("isJudge6", messageSource.getMessage("report.type.survey", null, locale));
		header.put("isJudge7", messageSource.getMessage("report.type.reference", null, locale));
		header.put("isReport1", messageSource.getMessage("report.type.fullReport1", null, locale) 
				+ messageSource.getMessage("report.type.fullReport", null, locale));
		header.put("isReport2", messageSource.getMessage("report.type.fullReport2", null, locale) 
				+ messageSource.getMessage("report.type.fullReport", null, locale));
		
		try {
			Date d = new Date();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
			String title = String.format("%s_%s", messageSource.getMessage("report.title", null, locale), sdf.format(d));
			
			List<ReportVO> list = reportService.selectRecordListAll(ReportCommon.setSearchUserInfo(reportSearchVO));
			
			model.addAttribute("excel", new ExcelExporter<ReportVO>(header, list, title));
			model.addAttribute("filename", title);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "excelView";
	}

	/**
	 * 일괄입력 화면을 반환한다.
	 * 
	 * @param model 모델객체
	 * @return 일괄입력 화면
	 * @throws Exception 기본예외처리
	 */
	@RequestMapping(value = "/offlineWrite.do", method = RequestMethod.GET)
	public String offlineAdd(final Model model) throws Exception {
		try {
			model.addAttribute("loginUserVO", UserUtil.getMemberInfo());
			
			model.addAttribute("judgeList", judgeService.selectJudgeCode());
			
			model.addAttribute("category1", cateService.getUseCategory1());
			model.addAttribute("category2", cateService.getUseCategory2());
			model.addAttribute("category3", cateService.getUseCategory3());
			model.addAttribute("category4", cateService.getUseCategory4());
			
			model.addAttribute("myGroupCode", ReportCommon.getMyGroupCode());
			
			if (!model.containsAttribute("reportVO")) {
				ReportVO reportVO = new ReportVO();
				LoginUserVO userVO = UserUtil.getMemberInfo();		
				
				reportVO.setInAgencyCode(ReportCommon.getAgencyCode(userVO.getPlace1()));
				reportVO.setInPlaceCode(userVO.getPlace1());
				reportVO.setInPlaceName(ReportCommon.getPlaceShortName(userVO.getPlace1Str()));
				reportVO.setInPlaceNum(reportService.selectPlaceNum(reportVO));
				
				model.addAttribute("reportVO", reportVO);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		
		return "report/offlineAdd.tiles";
	}

	/**
	 * 견문을 입력한 뒤 입력된 견문의 상세 조회 화면으로 이동한다.
	 * @param multiRequest 
	 * @param reportVO 견문 모델 객체
	 * @param bindingResult 
	 * @param model 
	 * @param status 
	 * @return String 뷰 이름
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping(value = "/offlineWrite.do", method = RequestMethod.POST)
	public String offlineAdd(final MultipartHttpServletRequest multiRequest, @ModelAttribute("reportVO") final ReportVO reportVO, 
			final BindingResult bindingResult, final Model model, final SessionStatus status) throws Exception {
		// 사용자 인증 검사
		Boolean isAuthenticated = EgovUserDetailsHelper.isAuthenticated();
		if (isAuthenticated) {
			// 유효성 검사
			beanValidator.validate(reportVO, bindingResult);
			if (bindingResult.hasErrors()) {
				return offlineAdd(model);
			}

			MemberVO memberVO = new MemberVO();
			memberVO.setUserid(reportVO.getInUserid());
			memberVO.setUsertype(reportVO.getInType());
			memberVO = memberService.select(memberVO);
			// 보고자 정보
			reportVO.setInName(memberVO.getName());
			reportVO.setInPlaceCode(memberVO.getPlace1());
			reportVO.setInPlaceName(ReportCommon.getPlaceShortName(memberVO.getPlace1Str()));
			reportVO.setInPlaceNum(reportService.selectPlaceNum(reportVO));
			reportVO.setInAgencyCode(ReportCommon.getAgencyCode(reportVO.getInPlaceCode()));
			reportVO.setInPlace1(memberVO.getPlace1Str());
			reportVO.setInPlace2(memberVO.getPlace2Str());
			reportVO.setInPosition(memberVO.getPositionStr());
			reportVO.setInIp(multiRequest.getRemoteAddr());
			if (UserType.FA.equals(reportVO.getInType())) {
				reportVO.setInType("1");
			} else {
				reportVO.setInType("2");
			}
			
			// 보고일 파싱
			String infoDate = reportVO.getStrInfodate().toString();
			reportVO.setInInfoYear(Integer.valueOf(infoDate.split("-")[0]));
			reportVO.setInInfoMonth(Integer.valueOf(infoDate.split("-")[1]));
			reportVO.setInInfoDay(Integer.valueOf(infoDate.split("-")[2]));
			
			// 상태코드 처리
			int offGroupCode = ReportCommon.getGroupCode(memberVO.getPlace1());
			if (reportVO.getInReport() > 0) {
				reportVO.setInStateCode(String.valueOf(offGroupCode + 1) + "1");
			} else if (reportVO.getInJudge() > 0 && reportVO.getInReport() <= 0) {
				reportVO.setInStateCode(String.valueOf(offGroupCode) + "4");
			} else {
				reportVO.setInStateCode(String.valueOf(offGroupCode) + "1");
			}
			
			// 일괄보고 정보
			LoginUserVO loginUserVO = UserUtil.getMemberInfo();
			reportVO.setInOfflineType(String.valueOf(loginUserVO.getType()));
			reportVO.setInOfflineUserid(loginUserVO.getUserid());
			
			switch (offGroupCode) {
			case 1:
				reportVO.setInJudge1(reportVO.getInJudge());
				reportVO.setInReport1(reportVO.getInReport());
				break;
			case 2:
				reportVO.setInJudge2(reportVO.getInJudge());
				reportVO.setInReport2(reportVO.getInReport());
				break;
			case 3:
				reportVO.setInJudge3(reportVO.getInJudge());
				reportVO.setInReport3(reportVO.getInReport());
				break;
			case 4:
				reportVO.setInJudge4(reportVO.getInJudge());
				reportVO.setInReport4(reportVO.getInReport());
				break;
			case 5:
				reportVO.setInJudge5(reportVO.getInJudge());
				reportVO.setInReport5(reportVO.getInReport());
				break;
			case 6:
				reportVO.setInJudge6(reportVO.getInJudge());
				reportVO.setInReport6(reportVO.getInReport());
				break;
			default:
				break;
			}
			
			// 파일 저장 및 데이터 입력
			final Map<String, MultipartFile> fileMap = multiRequest.getFileMap();
			HashMap<String, Object> map = reportService.insert(reportVO, fileMap);

			status.setComplete();

			int seq = (Integer) map.get("seq");
			int result = (Integer) map.get("result");
			if (result == 1 && seq > 0) {
				return "redirect:/report/update.do?inSeq=" + seq;
			}
		}		
		return "error/bizError";
	}

}
