/*
 * MosP - Mind Open Source Project         http://www.mosp.jp/
 * Copyright (C) 1987-2008 MIND Co., Ltd.  http://www.e-mind.co.jp/
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package jp.mosp.report.action;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import jp.mosp.common.CommonConst;
import jp.mosp.common.action.MosPAction;
import jp.mosp.common.common.MospConst;
import jp.mosp.common.common.MospException;
import jp.mosp.common.common.MospUtility;
import jp.mosp.common.common.PoiUtility;

import jp.mosp.payroll.vo.AttendanceExportCardVo;

import jp.mosp.report.dao.AttendanceManagementDao;
import jp.mosp.report.dto.AttendanceManagementDto;

public class AttendanceManagementAction extends MosPAction{

	// コマンド
	private static final String CMD_ATTENDANCE_MANAGEMENT		= "R1052";

	//フィールド
	protected List<AttendanceManagementDto>	managementList;

	private int		i			= 0;
	private int		r			= 0;	//Row(行) 0〜
	private int		pageno		= 0;	//ページ数
	private int		endpagel	= 50;	//1ページの最終行数
	private int		gyol		= 2;	//明細の改行数
	private int		titlel		= 3;	//1ページのタイトル印刷位置
	private int		firstl		= 8;	//1ページの明細開始位置
	private int		endl		= 50;	//最終位置getLastRow()で取得
	private int		lastl		= 46;	//1ページの明細最終行(合計行は含まない)
	private int		totall		= 48;	//1ページの合計印刷行	
	private String		file1		= "";
	private int		printcnt	= 0;

	// エクセル・セル番号
	private int		cc[]		= {12,19,26,33,40,47,54,61,68,75,82,89,96,103,110};
	// 明細項目定義 0-14上段　15-29下段
	private int		detail[]	= new int[30];
	// 合計項目定義 0-14上段　15-29下段
	private int		total[]		= new int[30];

	private String		simei			= " ";
	private double		snissu			= 0;
	private int    	kinmuji			= 0;
	private int      	kyukeiji		= 0;
	private double   	yukyu			= 0;
	private double  	tokukyu			= 0;
	private double  	kekkin			= 0;
	private double    	skekkin			= 0;
	private int        tisokai			= 0;
	private int       	tijikan			= 0;
	private int    	zajikan    		= 0;
	private int   		ksjikan    		= 0;
	private int     	snjikan    		= 0;
	private int      	kaikin     		= 0;
	private int      	syokujikaisu 	= 0;
	private int       	cyokukaisu1 	= 0;
	private int     	cyokukaisu2 	= 0;
	private int      	cyokukaisu3 	= 0;
	private int      	hokakaisu1   	= 0;
	private int      	hokakaisu2   	= 0;
	private int       	hokakaisu3		= 0;
	private int     	hokakaisu4		= 0;
	private int       	hokakaisu5		= 0;

	private String sectionName = "";

	/**
	 * コンストラクタ
	 */
	public AttendanceManagementAction() {
		super();
		setNeedProcSeq(false);
	}

	/**
	 * アクション
	 */
	public void action() throws Exception {		
		// DBコネクション取得
		getConnection();
		// VOの取得
		AttendanceExportCardVo vo = new AttendanceExportCardVo();
		vo.initVo(cfg, msg, cmd, aspUser, user);
		// VO及びフォワード先URLの設定
		setVo(vo);
		setUrl(vo.getRetUrl());
		session.setAttribute(MospConst.ATT_FORMER_VO, vo);
		// コマンド毎の処理
		if (cmd.equals(CMD_ATTENDANCE_MANAGEMENT)) {
			// パラメータ取得
			vo.setParams(request);
			Date targetMonth = util.getYearMonth(vo.getPltYear(), vo.getPltMonth());			
			// ユーザー情報取得
			getInfo(user.getUserId());
			// 所属名設定
			if (vo.getPltSection().equals(CommonConst.NAM_COMMON_STRING_INITIAL_VALUE)) {
				sectionName = CommonConst.NAM_ALL_SECTION;
			} else {
				sectionName = getSectionInfo(vo.getPltSection()).getSName();
			}
			// データ取得
			getManagementList(targetMonth, vo.getPltSection());
			// 帳票作成
			PoiUtility poi = makeManagement(targetMonth);
			// 帳票設定
			StringBuffer fileName = new StringBuffer();
			fileName.append(util.convDateToStringYearMonth(targetMonth));
			fileName.append(CommonConst.FILE_NAME_SEPARATOR);
			fileName.append(vo.getPltSection());
			fileName.append(CommonConst.FILE_NAME_SEPARATOR);
			fileName.append(CommonConst.FILE_SAMP_M_KINTAIKANRI);
			request.setAttribute(MospConst.ATT_FILE_NAME, fileName.toString());
			request.setAttribute(MospConst.ATT_FILE_OBJECT, poi.getWorkbook());
		} else {
			throw new MospException(MospConst.EX_CMD_INVALID);
		}
	}	

	/**
	 * データ取得
	 * @param targetMonth 対象月
	 * @throws Exception
	 */
	private void getManagementList(Date targetMonth, String scode) throws Exception {
		// DBコネクション取得
		if (conn == null) {
			getConnection();
		}
		// パラメータ設定
		String target = MospUtility.getYear (targetMonth) + CommonConst.STR_SEPARATOR + MospUtility.getMonth(targetMonth);
		// 検索
		AttendanceManagementDao dao = new AttendanceManagementDao();
		dao.initDao(cfg, cmd, aspUser, user, conn);
		managementList = new ArrayList<AttendanceManagementDto>();
		managementList = dao.findForCondition(target, scode);
	}

	/**
	 * 勤怠管理情報一覧作成
	 * @param managementList
	 * @param targetMonth
	 * @return PoiUtilityインスタンス
	 * @throws Exception 
	 */
	private PoiUtility makeManagement(Date targetMonth) throws Exception {
		// DBコネクション取得
		if (conn == null) {
			getConnection();
		}
		// 帳票作成準備
		PoiUtility poi = new PoiUtility();
		poi.crtNewDocR(0, cfg.getProperty(MospConst.PPT_APP_DOCBASE) + CommonConst.TEMPLATE_M_KINTAIKANRI);
		// ヘッダー情報設定
		prtTitle(targetMonth, poi);
		// データ表示
		Iterator<AttendanceManagementDto> it = managementList.iterator();
		while(it.hasNext()){
			AttendanceManagementDto dto = it.next();
			simei 		= dto.getSimei();
			snissu 		= Double.valueOf(dto.getSNissu());
			kinmuji 	= Integer.valueOf(dto.getKinmuJil());
			kyukeiji 	= Integer.valueOf(dto.getKyukeiJi());
			yukyu 		= Double.valueOf(dto.getYukyu());
			tokukyu 	= Double.valueOf(dto.getTokuKyu());
			kekkin 		= Double.valueOf(dto.getKekkin());
			skekkin 	= Double.valueOf(dto.getSKekkin());
			tisokai 	= Integer.valueOf(dto.getTiSoKai());
			tijikan 	= Integer.valueOf(dto.getTiJikan());
			zajikan 	= Integer.valueOf(dto.getZaJikan());
			ksjikan 	= Integer.valueOf(dto.getKsJikan());
			snjikan 	= Integer.valueOf(dto.getSnJikan());
			kaikin 		= Integer.valueOf(dto.getKaikin());
			syokujikaisu= Integer.valueOf(dto.getSyokujiKaisu());
			cyokukaisu1 = Integer.valueOf(dto.getCyokuKaisu1());
			cyokukaisu2 = Integer.valueOf(dto.getCyokuKaisu2());
			cyokukaisu3 = Integer.valueOf(dto.getCyokuKaisu3());
			hokakaisu1 	= Integer.valueOf(dto.getHokaKaisu1());
			hokakaisu2 	= Integer.valueOf(dto.getHokaKaisu2());
			hokakaisu3 	= Integer.valueOf(dto.getHokaKaisu3());
			hokakaisu4 	= Integer.valueOf(dto.getHokaKaisu4());
			hokakaisu5 	= Integer.parseInt(dto.getHokaKaisu5());
			// 明細印刷
			prtDetail(targetMonth,poi);
			addTotalg();	//合計
		}
		if (printcnt > 0) {
			// 総合計印刷
			prtTotalg(poi);
			prtEnding(poi);
		} else {
			// データ無し印刷
			prtNothing(targetMonth,poi);
		}
		return poi;
	}

	/**
	 * タイトル印刷メソッド
	 * @param targetMonth
	 * @param poi
	 * @throws Exception
	 */
	private void prtTitle(Date targetMonth, PoiUtility poi) throws Exception{
		// 改ページ
		pageno ++;
		//タイトル印刷位置算出
		r = (pageno - 1) * endpagel + (titlel - 1);
		//タイトル,日付
		r++;
		// 年月日
		poi.prtItem(r,  6, MospUtility.getYear (targetMonth) );
		poi.prtItem(r, 12, MospUtility.getMonth(targetMonth) );
		// 所属
		poi.prtItem(r, 93, sectionName);
		// 明細印刷位置算出
		r = (pageno - 1) * endpagel + (firstl - 1 - gyol);
	}

	/**
	 * @param targetMonth
	 * @param poi
	 * @throws Exception
	 */
	private void prtDetail(Date targetMonth,PoiUtility poi) throws Exception{
		// 改頁確認
		chkNewPage(targetMonth,poi);
		// 支給項目設定
		detail[0] 	= (int) snissu;
		detail[1] 	= kinmuji;
		detail[2] 	= zajikan;
		detail[3] 	= snjikan;
		detail[4] 	= tijikan;
		detail[5] 	= tisokai;

		detail[7] 	= syokujikaisu;
		detail[8] 	= cyokukaisu2;
		detail[9] 	= hokakaisu1;
		detail[10] 	= hokakaisu3;
		detail[11] 	= hokakaisu5;
		detail[12] 	= (int) yukyu;
		detail[13] 	= (int) tokukyu;

		//控除項目設定
		detail[16] 	= kyukeiji;
		detail[17] 	= ksjikan;

		detail[22] 	= cyokukaisu1;
		detail[23] 	= cyokukaisu3;
		detail[24] 	= hokakaisu2;
		detail[25] 	= hokakaisu4;
		detail[26] 	= kaikin;
		detail[27] 	= (int) kekkin;
		detail[28] 	= (int) skekkin;

		// 氏名
		poi.prtItem( r,  1, simei);

		// 上段項目
		poi.prtItem( r, cc[0], detail[0]);
		poi.prtItem( r, cc[1], getHourString(util.convIntegerTimeToDoubleTime(detail[1])));
		poi.prtItem( r, cc[2], getHourString(util.convIntegerTimeToDoubleTime(detail[2])));
		poi.prtItem( r, cc[3], getHourString(util.convIntegerTimeToDoubleTime(detail[3])));
		poi.prtItem( r, cc[4], getHourString(util.convIntegerTimeToDoubleTime(detail[4])));
		poi.prtItem( r, cc[5], detail[5]);
		poi.prtItem( r, cc[6], detail[6]);
		poi.prtItem( r, cc[7], detail[7]);
		poi.prtItem( r, cc[8], detail[8]);
		poi.prtItem( r, cc[9], detail[9]);
		poi.prtItem( r, cc[10], detail[10]);
		poi.prtItem( r, cc[11], detail[11]);
		poi.prtItem( r, cc[12], detail[12]);
		poi.prtItem( r, cc[13], detail[13]);
		// 下段項目
		poi.prtItem( r+1, cc[0], "");
		poi.prtItem( r+1, cc[1], getHourString(util.convIntegerTimeToDoubleTime(detail[16])));
		poi.prtItem( r+1, cc[2], getHourString(util.convIntegerTimeToDoubleTime(detail[17])));

		poi.prtItem( r+1, cc[6], detail[18]);
		poi.prtItem( r+1, cc[7], detail[22]);
		poi.prtItem( r+1, cc[8], detail[23]);
		poi.prtItem( r+1, cc[9], detail[24]);
		poi.prtItem( r+1, cc[10], detail[25]);
		poi.prtItem( r+1, cc[11], detail[26]);
		poi.prtItem( r+1, cc[12], detail[27]);
		poi.prtItem( r+1, cc[13], detail[28]);
		// 明細印刷件数
		printcnt ++;
	}

	/**
	 * 合計メソッド
	 */
	private void addTotalg(){
		//総合計
		for (i = 0; i <= 29; i ++) {
			total[i] += detail[i];
		}
	}

	/**
	 * 合計印刷位置算出
	 * @param poi
	 * @throws Exception
	 */
	private void prtTotalg(PoiUtility poi) throws Exception{		
		r = (pageno - 1) * endpagel + (totall - 1);
		// 支給項目
		poi.prtItem( r, cc[0], total[0]);
		poi.prtItem( r, cc[1], getHourString(util.convIntegerTimeToDoubleTime(total[1])));
		poi.prtItem( r, cc[2], getHourString(util.convIntegerTimeToDoubleTime(total[2])));
		poi.prtItem( r, cc[3], getHourString(util.convIntegerTimeToDoubleTime(total[3])));
		poi.prtItem( r, cc[4], getHourString(util.convIntegerTimeToDoubleTime(total[4])));
		poi.prtItem( r, cc[5], total[5]);
		poi.prtItem( r, cc[6], total[6]);
		poi.prtItem( r, cc[7], total[7]);
		poi.prtItem( r, cc[8], total[8]);
		poi.prtItem( r, cc[9], total[9]);
		poi.prtItem( r, cc[10], total[10]);
		poi.prtItem( r, cc[11], total[11]);
		poi.prtItem( r, cc[12], total[12]);
		poi.prtItem( r, cc[13], total[13]);
		// 控除項目
		poi.prtItem( r+1, cc[1], getHourString(util.convIntegerTimeToDoubleTime(total[16])));
		poi.prtItem( r+1, cc[2], getHourString(util.convIntegerTimeToDoubleTime(total[17])));

		poi.prtItem( r+1, cc[6], total[21]);
		poi.prtItem( r+1, cc[7], total[22]);
		poi.prtItem( r+1, cc[8], total[23]);
		poi.prtItem( r+1, cc[9], total[24]);
		poi.prtItem( r+1, cc[10], total[25]);
		poi.prtItem( r+1, cc[11], total[26]);
		poi.prtItem( r+1, cc[12], total[27]);
		poi.prtItem( r+1, cc[13], total[28]);
		// 明細印刷件数
		printcnt++;
	}

	/**
	 * 新しい頁作成メソッド
	 * @param targetMonth
	 * @param poi
	 * @throws Exception
	 */
	private void chkNewPage(Date targetMonth, PoiUtility poi) throws Exception{
		// オープン
		if (pageno == 0) {
			// Pageを再生成
			crtNewDoc(poi);
			// タイトル印刷
			prtTitle(targetMonth, poi);
		}
		if (r >= ((pageno - 1) * endpagel + (lastl - gyol))) {
			// オーバーフロー又は最初の印刷の時、タイトル印刷
			prtTitle(targetMonth, poi);
		}
		// 改行
		r += gyol;
	}

	/**
	 * 新しい頁作成メソッド
	 * @param poi
	 * @throws Exception
	 */
	private void crtNewDoc( PoiUtility poi) throws Exception{
		poi.crtNewDocR(0, file1);
		// 最終行取得
		endl = poi.getLastRow();
	}

	/**
	 * データ無し印刷メソッド
	 * @param targetMonth
	 * @param poi
	 * @throws Exception
	 */
	private void prtNothing(Date targetMonth, PoiUtility poi) throws Exception{
		// 改頁確認
		chkNewPage(targetMonth, poi);
		poi.prtItem( 7, 1, CommonConst.MSG_ATTENDANCE_REPORT_NO_DATA);
	}

	/**
	 * 帳票終了
	 * @param poi
	 * @throws Exception
	 */
	private void prtEnding(PoiUtility poi) throws Exception{
		// 印刷ｙ座標
		// 終了後の最初の行
		r = pageno * endpagel;
		boolean syori =  true;
		// 残り行を削除する
		for (; r <= endl; r++) {
			if (syori) {
				poi.dltRow(r);
			}
		}
	}

}
