package com.csc.library.timeattendance;

import java.rmi.RemoteException;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

import bsh.Interpreter;

import com.csc.library.database.StaticConfig;
import com.csc.library.databean.Memployee_ta;
import com.csc.library.databean.Mtime0;
import com.csc.library.databean.Ttime_current1;
import com.csc.library.process.CalculateVacation_New;
import com.csc.library.process.RoundingTime;
import com.csc.library.session.DbInquiry;
import com.csc.library.session.DbRecord;
import com.csc.library.session.InitialInquiry;
import com.csc.library.session.InitialRecord;
import com.csc.library.utilities.CscCalendar;
import com.csc.library.utilities.CscTime;
import com.csc.library.utilities.MyLog;
import com.csc.library.utilities.UProfile;
import com.csc.library.utility.DHMConvert;

public class ManageEmpLeaveStat {
	public Memployee_ta empRec ;
	public DbRecord grpRec, grpRecBranch ;
	private UProfile upf ;
	
	private String employeeid ;
	private String eventgrpid ;
	private String remain ;
	private String limit ;
	private String used ;
	private String exc_absentid = "" ;
	private String event_filter = "";
	 
	private HashMap hmLvType = new HashMap(); /* �纻���������ҷ����� */
	
	private int used_count = 0;
	private int[] lvcount = {0, 0, 0, 0};	/* �ӹǹ���駢ͧ����������� ����ѹ,��.,������� ��Ф��觺��� */
	
	private DbRecord absentProp ;	/* ����š���Ҥ��駹��  */
	
	private CscCalendar reqdate_st = null;	/* ��˹��ѹ������������ ���ͤӹdz���Է�ԡ���� */
	private CscCalendar reqdate_en = null;	/* ��˹��ѹ�������ش�� ���ͤӹdz���Է�ԡ���� */
	
	public CscCalendar normalLeaveStart ;	/* �Է���ҷ�����������*/
	public CscCalendar normalLeaveEnd ;		/* �Է���ҷ��������ش */
	public CscCalendar vacationStart ;		/* �Է���Ҿѡ��͹������� */
	public CscCalendar vacationEnd ;		/* �Է���Ҿѡ��͹����ش */
	
	private boolean calActual = false;		/* ʶҹе�ͧ��äӹdz limit �����֧�ҡ Memployee.vacation1 */

	public ManageEmpLeaveStat(UProfile upf,String empid){ /* ����кػ����� ��ͧ��÷���������� */
		setUProfile(upf);
		setEmployee(empid);
		
		initialEmp(this);
		initialEventGrp(this);
		initialDateConfig(this);	/* ��˹��ѹ���������� ����ش �է�����ҳ */
		
		initialLimit();	/* ��˹��Է�� ,�����Ф������ �ء����������� */
		initialUsed();	/* �ӹdz�ʹ��� */
	}
	
	public ManageEmpLeaveStat(UProfile upf,String empid,StringBuffer con){	/* �к����͹� */
		setUProfile(upf);
		setEmployee(empid);
		setFilter(con);
		
		initialEmp(this);
		initialEventGrp(this);
		initialDateConfig(this);	/* ��˹��ѹ���������� ����ش �է�����ҳ */
		
		initialLimit();	/* ��˹��Է�� ,�����Ф������ �ء����������� */
		initialUsed();	/* �ӹdz�ʹ��� */
	}
	
	public ManageEmpLeaveStat(UProfile upf,String empid,String eventgrp){	/* �кػ���������� */
		setUProfile(upf);
		setEmployee(empid);
		setEventGrp(eventgrp);
		
		initialEmp(this);
		initialEventGrp(this);
		initialDateConfig(this);	/* ��˹��ѹ���������� ����ش �է�����ҳ */
		
		initialLimit();	/* ��˹��Է�� ,�����Ф������ �ء����������� */
		initialUsed();	/* �ӹdz�ʹ��� */
	}
	
	public ManageEmpLeaveStat(UProfile upf,String empid,String eventgrp,DbRecord absentProp){	/* �кػ���������� */
		setUProfile(upf);
		setEmployee(empid);
		setEventGrp(eventgrp);
		
		initialEmp(this);
		initialEventGrp(this);
		initialDateConfig(this);	/* ��˹��ѹ���������� ����ش �է�����ҳ */
		
		this.absentProp=absentProp;
		initialLimit();	/* ��˹��Է�� ,�����Ф������ �ء����������� */
		initialUsed();	/* �ӹdz�ʹ��� */
	}
	
	public void setFilter(StringBuffer con){
		this.event_filter = con.toString() ;
	}
	
	public void setAbsentProp(DbRecord absent){
		this.absentProp = absent ;
	}
	
	public void clearStat(){
		this.limit = "";
		this.remain = "";
		this.used = "";
		this.used_count = 0;
	}
	
	public void setUProfile(UProfile upf){
		this.upf = upf;
	}
	
	public void setEmployee(String empid){
		this.employeeid = empid;
	}
	
	public void setEventGrp(String eventgrp){
		this.eventgrpid = eventgrp;
	}
	
	public String getEmployeeid(){
		return this.employeeid;
	}
	
	public String getEventGrp(){
		return this.eventgrpid;
	}
	
	public void setExceptAbsentID(String abid){
		this.exc_absentid = abid ;
	}
	
	/* �֧�����ž�ѡ�ҹ */
	private void initialEmp(ManageEmpLeaveStat ms){
		try {
			empRec = (Memployee_ta) new InitialRecord(this.upf).getDbRecord("MEMPLOYEE_TA");
			empRec.setColumn("*");
			empRec.setParam("rsc_skip","true");
			empRec.set("employeeid", ms.getEmployeeid());
			empRec.set("companyid", this.upf.get("companyid"));
			if(empRec.search() == 1){
				MyLog.debug("!! Employee found for managing leave stat !!");
			}else{
				MyLog.debug("!! Employee not found for managing leave stat [" + ms.getEmployeeid() + "]");
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
	}
	
	/* �֧�����Ż���������� */
	private void initialEventGrp(ManageEmpLeaveStat ms){
		try {
			if(ms.getEventGrp() == null || ms.getEventGrp().equals("")){
				DbInquiry inq = null;
				
				if(isLeaveLimitByBranch()){ /* �������Ẻ��˹�����Ң�������� */
					inq = new InitialInquiry(this.upf).getDbInquiry("MEVENTGRP1");
					
					if(this.event_filter.length() > 0){
						inq.setFilter("branchid='"+this.empRec.getString(getLeaveBranchField())+"' and " + this.event_filter);
					}else{
						inq.setFilter("branchid='"+this.empRec.getString(getLeaveBranchField())+"'");
					}
				}else{ /* Ẻ��� (����¡����Ң�) */
					inq = new InitialInquiry(this.upf).getDbInquiry("MEVENTGRP");

					if(this.event_filter.length() > 0){
						inq.setFilter(this.event_filter);
					}
				}
				
				inq.setColumn("*");
				inq.refresh();
				
				while(inq.next()){
					LeaveStatProp lsp = new LeaveStatProp();
					lsp.setLvData(inq.getCurrentDbRecord().cloneRecord(false));

					hmLvType.put(inq.getString("eventgrpid"), lsp);
				}
			}else{
				clearStat();
				
				DbInquiry inq = null;
				if(isLeaveLimitByBranch()){ /* �������Ẻ��˹�����Ң�������� */
					inq = new InitialInquiry(this.upf).getDbInquiry("MEVENTGRP1");
					inq.setFilter("eventgrpid='"+ms.getEventGrp()+"' and branchid='"+this.empRec.getString(getLeaveBranchField())+"'");
				}else{
					inq = new InitialInquiry(this.upf).getDbInquiry("MEVENTGRP");
					inq.setFilter("eventgrpid='"+ms.getEventGrp()+"'");
				}
					
				inq.setColumn("*");
				inq.refresh();
				while(inq.next()){
					grpRec = inq.getCurrentDbRecord().cloneRecord(true);
					LeaveStatProp lsp = new LeaveStatProp();
					lsp.setLvData(grpRec.cloneRecord(false));

					hmLvType.put(grpRec.getString("eventgrpid"), lsp);
					MyLog.debug("!! Eventgrp found for managing leave stat !!");
				}
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
	}
	
	/* ��˹��Է�Ԣͧ�ء������ */
	private void initialLimit(){ 
		try {
			Iterator it = hmLvType.keySet().iterator();
			for(; it.hasNext(); ){
				String key = (String) it.next();
				LeaveStatProp lsp = (LeaveStatProp) hmLvType.get(key); 
				getLimitLeave(lsp);
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
	}
	
	/* �ʹ������͡���� */
	public String getRemainLeave(String eventgrp){
		String remain = "00:00:00";
		try {
			DHMConvert dhm = new DHMConvert();
			int limit = 0;
			int used  = 0;
			float hourd = getHour_Day(this) ;
			
			if(hmLvType.containsKey(eventgrp)){
				LeaveStatProp lsp = (LeaveStatProp) hmLvType.get(eventgrp);
				
				limit = dhm.DHMToMin(lsp.getLimit(),Float.toString(hourd));
				used  = dhm.DHMToMin(lsp.getUsed(),Float.toString(hourd));
			}else{
				limit = dhm.DHMToMin(getLimitLeave(eventgrp),Float.toString(hourd));
				used  = dhm.DHMToMin(getLeaveUsed(eventgrp, this.absentProp),Float.toString(hourd));
			}
			
			if(limit >= used){
				remain = dhm.MinToDHM((limit - used),hourd);
			}else{
				remain = dhm.MinToDHM((used - limit),hourd);
				remain = "-" + remain;
				MyLog.debug("!! Leave used is greater than limit, result will be negative value !! ");
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return remain;
	}
	
	/* �֧��� limit ����� ���觡�Ѻ��ٻẺ �ѹ:��:�ҷ� */
	public String getLimitLeave(){
		return getLimitLeave(this.getEventGrp());
	}
	
	/* ��˹��Է�ԡ���һ�������ҧ � */
	public void getLimitLeave(LeaveStatProp lsp){
		String ANNUALLEAVE = "7";
		String LEAVEINADV = "A";
		
		DHMConvert dhm = new DHMConvert();
		String limit = "00:00:00";
		try {
			lsp.setHourd(getHour_Day(this));	/* ��. �ӧҹ����ѹ */
			
			if(lsp.getLvData().getString("daytype").equals(ANNUALLEAVE)){	/* �繻������Ҿѡ��͹��Шӻ� ��ͧ�֧��Ҩҡ vacation1 � memployee */
				
				/* limit �Фӹdz�ҡ  vacation0 (�Է��¡��) + vacation1 (�Է�ԻջѨ�غѹ) 
				 * ���բ������������ �Է��¡�ҹ�� �е�ͧ�礡Ѻ��� vacation_last 㹵��ҧ mvacation0 (memployee.vacation0 --> mvacation0.vacationid)
				 * ����Թ�ѹ����˹����㹿�Ŵ vacation_last ������������Ѻ��� vacation1
				 * */
				String v0 = (this.empRec.getString("vacation0")!=null&&!this.empRec.getString("vacation0").equals(""))?
						this.empRec.getString("vacation0"):"00:00:00";	/* �Է��¡�� */
				String v1 = (this.empRec.getString("vacation1")!=null&&!this.empRec.getString("vacation1").equals(""))?
						this.empRec.getString("vacation1"):"00:00:00";	/* �Է�Ԣͧ�ջѨ�غѹ */
				
				v1 = deductReqAnnualInAdvance(lsp, v1);	/* ź�Է�Ծѡ��͹��������ǧ˹�Ңͧ�ա�͹ */
				
				if(isVacation0StillActive()){	/* �ѧ����ö���Է��¡���� */
					int total = dhm.DHMToMin(v0, Double.toString(lsp.getHourd())) + dhm.DHMToMin(v1, Double.toString(lsp.getHourd()));
					lsp.setLimit(dhm.MinToDHM(total, lsp.getHourd()));
				}else{	/* ��ª�ǧ�������ö���Է��¡������ */
					int total = dhm.DHMToMin(this.getAnnualLeaveOnV0Period(lsp.getLvData().getString("eventgrpid"))
							, Double.toString(lsp.getHourd())) + dhm.DHMToMin(v1, Double.toString(lsp.getHourd()));
					lsp.setLimit(dhm.MinToDHM(total, lsp.getHourd()));
				}
			}else if(lsp.getLvData().getString("daytype").equals(LEAVEINADV)){
				lsp.setLimit(getLeaveInAdv(lsp));
			}else{	/* �繡���ҷ�������֧ limit �ҡ meventgrp.limit */
				lsp.setLimit(((lsp.getLvData().getInt("limit") <= 9)?"0"+lsp.getLvData().getString("limit"):lsp.getLvData().getString("limit")) + ":00:00");
			}
			
            // ��Ҿ�ѡ�ҹ�ѧ����㹪�ǧ���ͧ�ҹ �Է�Է������ж١᷹�մ����Է��㹪�ǧ���ͧ�ҹ
			//if (empRec.getString("status").equals("V")) { 
				/* �ó���Ẻ �������� eventchkleave �������¹�ҨѺ�ҡ Approve Date */
			
			//String eventchkleave = (String) StaticConfig.getConfigCompany(this.upf, "TA_chkleave");
			//	if(eventchkleave.indexOf(lsp.getLvData().getString("eventgrpid"))==-1){
			if(lsp.getLvData().getString("needapprovedate").equals("1")){
				if(!checkapprove_date()){
						//int lv_prob = getLimitProbation(lsp.getLvData().getString("eventgrpid"));
		                //lsp.setLimit(((lv_prob <= 9)?"0"+ Integer.toString(lv_prob):Integer.toString(lv_prob)) +":00:00");
					lsp.setLimit("00:00:00");
				}
			}
            //}
			
			hmLvType.put(lsp.getLvData().getString("eventgrpid"), lsp);
		}catch(Exception e){
			MyLog.error(this,e);
		}
	}
	
	/* �֧��� limit ����� ���觡�Ѻ��ٻẺ �ѹ:��:�ҷ� */
	public String getLimitLeave(String eventgrp){
		try {
			if(hmLvType.containsKey(eventgrp)){
				LeaveStatProp ls = (LeaveStatProp) hmLvType.get(eventgrp);
				return ls.getLimit() ;
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return "00:00:00";
	}
	
	/* ���ʶҹТͧ����ʴ��Է�ԡ���� (display_limit) ��  1 ���ʴ���� ����� 0 ���ʴ������ 00:00:00 */
	public boolean isLeaveTypeActive(){
		try {
			if(isLeaveLimitByBranch()){	/* �֧ limit ����Ң� */
				if(initEventGrpBranch()){
					return (grpRecBranch.getInt("display_limit")==1)?true:false;
				}else{
					MyLog.error(" !! event " + this.getEventGrp() + " for branch " + this.empRec.getString("branch") + " not found !!");
				}
			}else{
				if(grpRec != null){
					return (grpRec.getInt("display_limit")==1)?true:false;
				}
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return false;
	}
	
	public int getLimitProbation(String eventgrp){
		try {
			if(hmLvType.containsKey(eventgrp)){
				LeaveStatProp ls = (LeaveStatProp) hmLvType.get(eventgrp);
				return ls.getLvData().getInt("limit_probation") ;
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return 0 ;
	}
	
	public int getLimitProbation(){
		try {
			if(isLeaveLimitByBranch()){	/* �֧ limit ����Ң� */
				if(initEventGrpBranch()){
					return grpRecBranch.getInt("limit_probation");
				}else{
					MyLog.error(" !! event " + this.getEventGrp() + " for branch " + this.empRec.getString("branch") + " not found !!");
				}
			}else{
				if(grpRec != null){
					return grpRec.getInt("limit_probation");
				}
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return 0;
	}
	
	/* �ӹǹ���駷������ */
	public int getLimitAmount(){
		return getLimitAmount(this.getEventGrp());
	}
	
	/* �ӹǹ���駷������ */
	public int getLimitAmount(String eventgrp){
		int max = 0;
		try {
			if(grpRec == null){ initialEventGrp(this); }
			if(!grpRec.getString("eventgrpid").equals(eventgrp)){
				this.setEventGrp(eventgrp);
				initialEventGrp(this);
			}
			
			if(isLeaveLimitByBranch()){	/* �֧ limit ����Ң� */
				if(initEventGrpBranch()){
					max = grpRecBranch.getInt("limit_times");
				}else{
					MyLog.error(" !! event " + this.getEventGrp() + " for branch " + this.empRec.getString("branch") + " not found !!");
				}
			}else{
				if(grpRec != null){
					max = grpRec.getInt("limit_times");
				}
			}
			
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return max ;
	}
	
	/* ������鹻է�����ҳ� Mconfig */
	private String getBudgetYearStart(){
		String bgst = "";
		try {
			bgst = (String) StaticConfig.getConfigCompany(this.upf, "TA1003");
		}catch(Exception e){
			MyLog.error(this,e);
			bgst = new CscCalendar().getDDMMYYYY();
		}
		return bgst ;
	}
	
	/* ����ش�է�����ҳ� Mconfig */
	private String getBudgetYearEnd(){
		String bgen = "";
		try {
			bgen = (String) StaticConfig.getConfigCompany(this.upf, "TA1004");
		}catch(Exception e){
			MyLog.error(this,e);
			bgen = new CscCalendar().getDDMMYYYY();
		}
		return bgen ;
	}
	
	/* ������ѧ����ö�����Է��¡��������� */
	private boolean isVacation0StillActive(){
		try {
			CscCalendar today = new CscCalendar();
			CscCalendar lastAvailable = getVacationLast();	/* �Է��¡������֧�ѹ��� */
			CscCalendar startbudgetyear = new CscCalendar(getBudgetYearStart());	/* ������鹻է�����ҳ */
			CscCalendar endbudgetyear = new CscCalendar(getBudgetYearStart());		/* ����ش�է�����ҳ */
			
			if(today.afterDate(endbudgetyear)){ /* �ѹ�Ѩ�غѹ ��ª�ǧ�է�����ҳ������ �ʴ�����繡�ô���͹��ѧ  */
				return true ;
			}else if(lastAvailable.afterEqualsDate(new CscCalendar())){	/* ����ѹ�������ö���Է��¡�� ������ѧ�ѹ���Ѩ�غѹ�ʴ�����ѧ����ö���Է��¡���� */
				return true;
			}else{
				return false ;
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return false;
	}
	
	/* �� �ѹ��� ����ش�ͧ������Է��¡�� */
	private CscCalendar getVacationLast(){
		CscCalendar last = null;
		try {
			CscCalendar cscLeaveStart = new CscCalendar(getBudgetYearStart());	/* �ѹ���������鹻է�����ҳ */
            CscCalendar cscLeaveEnd = new CscCalendar(getBudgetYearEnd());		/* �ѹ�������ش�է�����ҳ */
			
			DbRecord mv0 = new InitialRecord(this.upf).getDbRecord("MVACATION0");
			mv0.setColumn("*");
			mv0.set("vacationid", this.empRec.getString("vacationcode"));
			mv0.set("companyid", this.empRec.getString("companyid"));
			if(mv0.search() == 1){
				String strLast = mv0.getString("vacation_last").replace(":", "-");	/* ��ҷ������ �ѹ-��͹ ,������ҧ 31-03*/
				
				if(strLast.equals("")) {	/* ��Ҥ�ҷ�������繪�ͧ��� ��˹�������ѹ��� 01 ��͹ 1 */
					strLast = "31-12";
				}

				if(strLast.split("-").length == 3){
					last = new CscCalendar(strLast);
					return last;
				}else{
					/* ��������ѹ�������ش�ͧ�Է��¡�ҷ������ö���� �����ҡѺ��ǧ�է�����ҳ� mconfig */
					last  = new CscCalendar(strLast + "-" + Integer.toString(cscLeaveStart.getYear()));
				}
				
				/* ����������㹪�ǧ�է�����ҳ �ʴ���һէ�����ҳ��Ẻ������ (���������� 01-01 �������ش 31-12 ��ͧ��Ѻ������������ ���͵�ͧ����������㹪�ǧ�է�����ҳ����˹�� mconfig */
				if(!(last.afterEqualsDate(cscLeaveStart) && last.beforeEqualsDate(cscLeaveEnd))){
					last.incYear(1);
				}
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return last;
	}
	
	/* �֧�����Ż���������� */
	public DbRecord getEventgrpProp(String eventgrp){
		try {
			if(!this.getEventGrp().equals(eventgrp)){
				this.setEventGrp(eventgrp);
				initialEventGrp(this);
			}
		} catch(Exception e){
			MyLog.error(this,e);
		}
		return this.grpRec ;
	}
	
	/* �������������������͹ ������� */
	private boolean isClearStatByMonth(String eventgrp){
		try {
			if(this.getEventgrpProp(eventgrp).getField("clear_leave_month") != null){
				if(this.getEventgrpProp(eventgrp).getString("clear_leave_month").equals("1")){
					return true;
				}else{
					return false;
				}
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return false;
	}
	
	/* �������������������͹ ������� */
	private boolean isClearStatByMonth(LeaveStatProp lsp){
		try {
			if(lsp.getLvData().getField("clear_leave_month") != null){
				if(lsp.getLvData().getString("clear_leave_month").equals("1")){
					return true;
				}else{
					return false;
				}
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return false;
	}
	
	/* �֧�������ʹ��������������� */
	public String getLeaveUsed(String eventgrp, DbRecord absentprop){
		String lv = "00:00:00";
		try {
			used_count = 0;
			
			CscCalendar cscLeaveStart = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1001"));
            CscCalendar cscLeaveEnd = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1002"));
            CscCalendar cscVacationStart = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1003"));
            CscCalendar cscVacationEnd = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1004"));
            
            CscTime lv_hour = new CscTime();
            
            LeaveStatProp lsp = null ;
            if(hmLvType.containsKey(eventgrp)){
            	lsp = (LeaveStatProp) hmLvType.get(eventgrp);
            	grpRec = lsp.getLvData() ;
            	
            	if(isClearStatByMonth(lsp)){	/* ����������ʹ�����ء��͹ �����੾�Ъ�ǧ��͹������ */
                	CscCalendar curmonth_st = new CscCalendar(absentprop.getString("start_date"));
                	CscCalendar curmonth_en = new CscCalendar(absentprop.getString("start_date"));
                	curmonth_st.setDate(1); /* ��������ѹ��� 1 */
                	curmonth_en.setDate(curmonth_en.getEndDateOfMonth());
                	
                	cscLeaveStart = new CscCalendar(curmonth_st.getYYYYMMDD());	/* ��˹��ѹ������������͹����᷹ */
                	cscLeaveEnd = new CscCalendar(curmonth_en.getYYYYMMDD());	/* ��˹��ѹ�������ش�ͧ��͹����᷹ */
                }
            	
            	/* ����������� */
                String eventlist = "";
                if(grpRec.getField("sharelimit_event") != null && !grpRec.getString("sharelimit_event").equals("")){
                	eventlist = "(";
                	eventlist += "lv_type in ('" + eventgrp + "','" + grpRec.getString("sharelimit_event") + "') ";
                	eventlist += " OR lv_type in (select eventgrpid from " + grpRec.getActualName() + " where sharelimit_event in ('" + eventgrp + "','" + grpRec.getString("sharelimit_event") + "'))" ;
                	eventlist += ")";
                }else{
                	eventlist += "lv_type = '" + eventgrp + "'";
                }
    			
    			DbInquiry leave = new InitialInquiry(this.upf).getDbInquiry("TLEAVE_SUMMARY");
    			leave.setColumn("*");
    			String filter = eventlist + " and employeeid = '" + this.empRec.getString("employeeid") 
    					+ "' and dateid between '" + cscLeaveStart.getYYYYMMDD() 
    					+ "' and '"+ cscLeaveEnd.getYYYYMMDD() +"'" ;
    			
    			if(!absentprop.getString("absentid").equals("")){ /* �������Ţ����͡��÷���˹����͡���¡��� �����Ҥӹdz�ʹ���  */
    				filter += " and docid != '" + absentprop.getString("absentid")+ "'";
    			}
    			
    			leave.setFilter(filter);
    			leave.refresh();
    			
    			String docid = "";
    			while(leave.next()){
    				lv_hour.add(Float.parseFloat(leave.getString("m_lv")));
    				
    				if(!docid.equals(leave.getString("docid"))){
    					docid = leave.getString("docid");
    					used_count++;
    				}
    			}
    			
    			/* �ó��Ҭһ��Ԩ ����˹�������� mconfig ��� �ʴ���ҵ�ͧ������ӹdz����ӹǹ������ª��Ե��ԧ  */
    			if(getFixFeneralLeave().equals(grpRec.getString("eventgrpid"))){
    				lv_hour = new CscTime();
    				lv_hour.add(this.getHisFuneralLeave());
    			}
    			
    			DHMConvert dhm = new DHMConvert(lv_hour.getFloat(), getHour_Day(this));
    			lv = dhm.parseDHM();
            }
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return lv;
	}
	
	/* �֧�������ʹ��������������� */
	public String getLeaveUsed(String eventgrp){
		try {
			if(hmLvType.containsKey(eventgrp)){
				LeaveStatProp lsp = (LeaveStatProp) hmLvType.get(eventgrp);
				return lsp.getUsed();
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return "00:00:00";
	}
	
	/* �֧�����Ũӹǹ���駡���Ңͧ�ʹ��������������� */
	public int getAmountLeaveUsed(String eventgrp, DbRecord absentprop) {
		int count = 0;
		try {
			if(!this.getEventGrp().equals(eventgrp)) {
				this.setEventGrp(eventgrp);
				initialEventGrp(this);
			}
			
			if(used_count > 0){ return used_count; }	/* �ӹdz������Ǩҡ getLeaveUsed() ��������� */
			
			CscCalendar cscLeaveStart = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1001"));
            CscCalendar cscLeaveEnd = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1002"));
            CscCalendar cscVacationStart = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1003"));
            CscCalendar cscVacationEnd = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1004"));
            
			if(isClearStatByMonth(eventgrp)){	/* ����������ʹ�����ء��͹ �����੾�Ъ�ǧ��͹������ */
            	CscCalendar curmonth_st = new CscCalendar(absentprop.getString("start_date"));
            	CscCalendar curmonth_en = new CscCalendar(absentprop.getString("start_date"));
            	curmonth_st.setDate(1); /* ��������ѹ��� 1 */
            	curmonth_en.setDate(curmonth_en.getEndDateOfMonth());
            	
            	cscLeaveStart = new CscCalendar(curmonth_st.getYYYYMMDD());	/* ��˹��ѹ������������͹����᷹ */
            	cscLeaveEnd = new CscCalendar(curmonth_en.getYYYYMMDD());	/* ��˹��ѹ�������ش�ͧ��͹����᷹ */
            }
			
			DbInquiry leave = new InitialInquiry(this.upf).getDbInquiry("TLEAVE_SUMMARY");
			leave.setColumn("*");
			leave.setFilter("lv_type = '" + eventgrp + "' and employeeid = '" + this.empRec.getString("employeeid") 
					+ "' and dateid between '" + cscLeaveStart.getYYYYMMDD() 
					+ "' and '"+ cscLeaveEnd.getYYYYMMDD() +"' and docid !='"+absentprop.getString("absentid")+"'" );
			leave.refresh();
			
			String docid = "";
			while(leave.next()){
				if(!docid.equals(leave.getString("docid"))){
					docid = leave.getString("docid");
					count++;
				}
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return count;
	}
	
	/* �֧�����Ũӹǹ���駡���Ңͧ�ʹ��������������� */
	public int getAmountLeaveUsed(){
		return getAmountLeaveUsed(this.getEventGrp());
	}
	
	/* �֧�����Ũӹǹ���駡���Ңͧ�ʹ��������������� */
	public int getAmountLeaveUsed(String eventgrp){
		try {
			if(hmLvType.containsKey(eventgrp)){
				LeaveStatProp lsp = (LeaveStatProp) hmLvType.get(eventgrp);
				return lsp.getCount();
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return 0;
	}
	
	public boolean isCountLeaveFormatOverLimit(DbRecord absent){
		try {
			int max = getCountLeaveFormatLimit(absent.getInt("leave_format"));
			int used = getCountLeaveUsedPerMonth(absent.getString("type_absent"), absent.getString("start_date"), absent.getString("leave_format"));
			
			if(max >= (used + 1)){
				return false ;
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return true;
	}
	
	/* �֧�ӹǹ���駵������������ (����ѹ, ������� - ���� ��� ��.) */
	public int getFormatLimit(int format){
		try {
			return lvcount[format];
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return 0 ;
	}
	
	public int getCountLeaveFormatLimit(int mode){
		try {
			if(isLeaveLimitByBranch()){
            	if(initEventGrpBranch()){
            		if(grpRecBranch.getField("month_limit0") == null ){	/* ����տ�Ŵ�������觤�� default ��Ѻ� */
            			return 99;
            		}else{
	            		if(mode == 0){
	            			return grpRecBranch.getInt("month_limit0");
	            		}else if(mode == 1){
	            			return grpRecBranch.getInt("month_limit1");
	            		}else if(mode == 2){
	            			return grpRecBranch.getInt("month_limit2");
	            		}else if(mode == 3){
	            			return grpRecBranch.getInt("month_limit3");
	            		}
            		}
				}else{
					MyLog.error(" !! Can not find eventgrp : " + grpRec.getString("eventgrpid") + " by branch : " + this.empRec.getString("branch"));
				}
            }else{
            	if(grpRec.getFieldList().indexOf("month_limit0") > -1){
            		if(mode == 0){
            			return grpRec.getInt("month_limit0");
            		}else if(mode == 1){
            			return grpRec.getInt("month_limit1");
            		}else if(mode == 2){
            			return grpRec.getInt("month_limit2");
            		}else if(mode == 3){
            			return grpRec.getInt("month_limit3");
            		}
            	}
            }
		}catch(Exception e){/* �ó�����տ�Ŵ�����к�����觤�� 99 �繤�� default ��������к��ӧҹ����� (����ö����) */
			MyLog.error(this,e);
			return 99; 
		}
		return 99 ;
	}
	
	/* �֧�����Ũӹǹ���駡���Ңͧ�ʹ��������������� */
	public int getCountLeaveUsedPerMonth(String eventgrp, String date){
		return getCountLeaveUsedPerMonth(eventgrp, date, "");
	}
	
	/* �֧�����Ũӹǹ���駡���Ңͧ�ʹ��������������� */
	public int getCountLeaveUsedPerMonth(String eventgrp, String date, String mode){
		int count = 0;
		try {
			CscCalendar cscLeaveStart = new CscCalendar(date);
            CscCalendar cscLeaveEnd = new CscCalendar(date);
            cscLeaveStart.setDate(1);
            cscLeaveEnd.setDate(cscLeaveStart.getEndDateOfMonth());
            
            /* leave format (0:full day, 1:hour, 2;first half, 3:second half */
            String lvformat = "";
            if(!mode.equals("")){	/* full day */
            	lvformat = " and leave_format = '" + mode + "'";
            }
        
			DbInquiry leave = new InitialInquiry(this.upf).getDbInquiry("Tabsent_nstda");
			leave.setColumn("*");
			String filter = "type_absent = '" + eventgrp + "' and employeeid = '" + this.empRec.getString("employeeid") 
					+ "' and start_date between '" + cscLeaveStart.getYYYYMMDD() 
					+ "' and '"+ cscLeaveEnd.getYYYYMMDD() +"'" + lvformat;
			
			if(!this.exc_absentid.equals("")){ /* �������Ţ����͡��÷���˹����͡���¡��� �����Ҥӹdz�ʹ���  */
				filter += " and absentid != '" + this.exc_absentid + "'";
			}
			
			leave.setFilter(filter);
			leave.refresh();
			
			count = leave.recCount();
			
			if(!mode.equals("")){	/* ������� */
				lvcount[Integer.parseInt(mode)] = count;
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return count;
	}
	
	/* ��. �ӧҹ����ѹ */
	public float getHour_Day(ManageEmpLeaveStat mg) {
        float value = 8;
        try {
            DbRecord inq1 = new InitialRecord(this.upf).getDbRecord("MTIME0");
            inq1.setColumn("time0id,companyid,edesc,tdesc,hour_d");    
            inq1.set("time0id", mg.empRec.getString("time0"));
            inq1.set("companyid", this.upf.get("companyid"));
            if (inq1.search()==1) {
                value = inq1.getFloat("hour_d");            
            } 
        } catch (Exception e) {
            MyLog.error(this, e);           
        }
        return value;
    }
	
	public float getLvPastLimit(){
		try {
			if(isLeaveLimitByBranch()){
            	if(initEventGrpBranch()){
            		return grpRecBranch.getFloat("lvpastlimit");
				}else{
					MyLog.error(" !! Can not find eventgrp : " + grpRec.getString("eventgrpid") + " by branch : " + this.empRec.getString("branch"));
				}
            }else{
				return grpRec.getFloat("lvpastlimit");
            }
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return 0 ;
	}
	
	/* ������͹��ѧ�Թ����˹�������� */
	public boolean isPastLimit(CscCalendar date, String leave_amount){
		int MODE = 0; 	/* ����͹��ѧ */
		boolean result = false;
		try {
			float days = findLeaveDays(date.getYYYYMMDD(), leave_amount, MODE);	/* �Ҩӹǹ�ѹ�����͹��ѧ */
			float lvpast = getLvPastLimit();
			
			/* ���������͹��ѧ�Թ����˹�������� */
			if(days > lvpast){
				result = true;
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return result;
	}
	
	public float getBeyondLimit(){
		try {
			if(isLeaveLimitByBranch()){
            	if(initEventGrpBranch()){
            		return grpRecBranch.getInt("lvfuturelimit");
				}else{
					MyLog.error(" !! Can not find eventgrp : " + grpRec.getString("eventgrpid") + " by branch : " + this.empRec.getString("branch"));
				}
            }else{
				return grpRec.getInt("lvfuturelimit");
            }
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return 0;
	}
	
	/* ������ǧ˹���Թ����˹�������� */
	public boolean isBeyondLimit(CscCalendar date, String leave_amount){
		int MODE = 1; 	/* ����ǧ˹�� */
		boolean result = false;
		try {
			float days = findLeaveDays(date.getYYYYMMDD(), leave_amount, MODE);	/* �Ҩӹǹ�ѹ�����ǧ˹�� */
			float lvfut = getBeyondLimit();
			
			/* ���������ǧ˹���Թ����˹�������� */
			if(days > lvfut){
				result = true;
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return result;
	}
	
	/* ��ͧ������ǧ˹�����ҧ���¡���ѹ */
	public float getLvAdvPeriod(){
		try {
			if(isLeaveLimitByBranch()){
            	if(initEventGrpBranch()){
            		return grpRecBranch.getInt("datebeforerequest");
            		//return grpRecBranch.getInt("lvadvperiod");
				}else{
					MyLog.error(" !! Can not find eventgrp : " + grpRec.getString("eventgrpid") + " by branch : " + this.empRec.getString("branch"));
				}
            }else{
				return grpRec.getInt("datebeforerequest");
            }
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return 0;
	}
	
	/* ������ǧ˹�����ҧ���µ������˹�������� */
	public boolean isInAdvPeriod(CscCalendar date){
		int MODE = 1; 	/* ����ǧ˹�� */
		boolean result = true;
		try {
			float days = date.subForDay(new CscCalendar());
			float lvadv = getLvAdvPeriod();
			
			/* ���������ǧ���ҧ���µ������˹�������� */
			if(lvadv == 0 || days <= 0){	// ��˹���� ����ǧ˹�� ����� 0 ���¤����������ͧ��
				result = false;
			}else if(days >= lvadv){	
				result = false;
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return result;
	}
	
	/* ���Ҩӹǹ�ѹ������ �����Ѻ�ѹ��ش �����ҧ�ҡ�ѹ���Ѩ�غѹ����ѹ ������Ѻ�礨ӹǹ�ѹ��͹��ѧ ������ǧ˹��  ��� mode ���������� (0 ��͹��ѧ, 1 ��ǧ˹��)*/
	public float findLeaveDays(String date, String leave_amount, int mode){
		int days = 0;    /* �ӹǹ�ѹ���ӹdz������ҧ�ҡ�ѹ���Ѩ��Ѻѹ */
		int _BEFORE = 0; /* 0 is before current date */
		int _AFTER = 1;  /* 1 is after current date  */
		int _ERROR = 99; /* �óշ������͹��ѧ ����繡���Ҥ�����ѹ���Ѩ�غѹ ����������繡������͹��ѧ �֧�絤������������ö���� (૵�ӹǹ�ѹ���� 99)*/
		int idxType;	 /* �������͡�������ǧ˹�� ���������͹��ѧ ���礨ҡ�ѹ������ ����ѹ���Ѩ�غѹ */
		
		boolean isBefore = false;
		
		Vector vDays = new Vector(); /* ���ѹ��� ��������Ἱ���������ѹ��ش */
		
        CscCalendar stGenWorkingSF = null; /* �ѹ����������Ἱ�������ҧ */
        CscCalendar enGenWorkingSF = null; /* �ѹ�������شἹ�������ҧ */
        WorkingShift wkShf = null;
		try {
			/* ��˹���ҵ���õ�ҧ � ���������ҧἹ��÷ӧҹ */
			String time0 = empRec.getDailyTime0id(new CscCalendar(date));
			
        	Mtime0 timeRec = (Mtime0) new InitialRecord(this.upf).getDbRecord("MTIME0");
            timeRec.set("time0id", time0); /* �����ʡ� ���͹���Ҥ�� prop �ͧ�� */
            timeRec.setColumn("*");
            timeRec.search();
            timeRec.setEmpRec(empRec);            
                
            /* ���ѹ�����������������ش ������ҧἹ��÷ӧҹ ������ѹ�Ѩ��Ѻѹ�֧�ѹ������ѹ�ش����㹡�����ҧἹ  */
            /* �� �� 11-11-2010 �֧ 13-11-2010 ����ѹ���Ѩ�غѹ��� 15-11-2010 */
            /* ���ҧἹ���ѹ��� 13-11-2010 - 15-11-2010 */
            CscCalendar stDate = new CscCalendar(date);
            CscCalendar curDate = new CscCalendar();
            curDate.setCSCTime(0.00);
            curDate.setSecond(0);

            /* ��˹��ѹ���������� �������ش 
             * �������͹��ѧ �ѹ���������鹨����ѹ������ ����ѹ����ش�����ѹ���Ѩ�غѹ
             * �������ǧ˹�� �ѹ���������鹨����ѹ���Ѩ�غѹ ����ѹ����شἹ�����ѹ���������鹷����� */
            if(stDate.afterEqualsDate(curDate)){
            	stGenWorkingSF = curDate;
               	enGenWorkingSF = stDate;
               	idxType = _AFTER;
               	isBefore = false;
            } else {
            	stGenWorkingSF = stDate;
               	enGenWorkingSF = curDate;
               	idxType = _BEFORE;
               	isBefore = true;
            }
			
            /* ��ҵç�Ѻ mode ���������� ������͹䢡������Ẻ���ǡѹ �� �觤�� mode 0 ������͹��ѧ �礨ҡ�ѹ�����������͹��ѧ��ԧ�֧�зӧҹ��� */
            if(idxType == mode){
	            /* ���ҧἹ */
	            wkShf = timeRec.genWorkingShift(new CscCalendar(stGenWorkingSF.getTimestamp()), new CscCalendar(enGenWorkingSF.getTimestamp()) , "true"); //�������ѹ��ش
	            wkShf.setUProfile(this.upf);
	            wkShf.setEmployeeid(this.empRec.getString("employeeid"));
	            wkShf.setEmprec(this.empRec);
	            wkShf.setEmpTimeCode(time0);
	            wkShf.adjust();    
	            
	            ManageAdjustChangeHoliday mac = new ManageAdjustChangeHoliday(this.upf);
	            wkShf.adjustChangeHoliday(mac.getAdjustChangeHolidayData(wkShf, this.empRec), this.upf);
                
                if(this.getEventDayType().equalsIgnoreCase("false") || this.getEventDayType().equals("F") || this.getEventDayType().equals("2")){
                	wkShf.removeStopShift();
                }

	            Iterator IT = wkShf.keySet().iterator();
	
	            /* ���ѹ����Ἱŧ� Vector */
	            while(IT.hasNext()){
	            	String dayKey = (String) IT.next();
	                DayShift dShift = (DayShift) wkShf.get(dayKey);
	                if (!dShift.isEmpty() || dShift.size()==1) {
	                	vDays.add(dayKey);
	                }
	            }
	            
	            /* �ӹdz�Ҩӹǹ�ѹ����� �֧�ѹ���Ѩ�غѹ 
	             * ������ҧ����͹��ѧ ����� 13-11-2010 - 15-11-2010 �ѹ���Ѩ�غѹ 18-11-2010 �ӹǹ�ѹ�����ҧ�ҡ�ѹ���Ѩ�غѹ ��� 3 �ѹ
	             * ������ҧ����ǧ˹�� ����� 20-11-2010 - 22-11-2010 �ѹ���Ѩ�غѹ 18-11-2010 �ӹǹ�ѹ�����ҧ�ҡ�ѹ���Ѩ�غѹ ��� 2 �ѹ*/
	            if(idxType == _BEFORE){ /* �ó�����͹��ѧ �Фӹdz�ѹ�������ش����� �֧�ѹ���Ѩ�غѹ �ѧ��鹨����Ѻ�ѹ����͹�ѹ����ش����� */
	            	/* ����� �����͹��ѧ��ԧ������� �ѹ�ش���¡���ҵ�ͧ�����͹�ѹ���Ѩ�غѹ �礨ӹǹ�ѹ���� �Ѻ�ӹǹ�ѹ������ҧ��ҡ������ҧἹ 
	            	 * �ӹǹ�ѹ������ҧ�ҡἹ ��ͧ�ҡ�������� 
	            	 * �� �� 18-11-2010 - 21-11-2010 �ѹ���Ѩ�غѹ��� 20-11-2010 
	            	 * Ἱ��÷ӧҹ ���١���ҧ�����ѹ��� 18-11-2010 - 20-11-2010 ��� 3 �ѹ
	            	 * �ӹǹ�ѹ������ 4 �ѹ ����ҡ���Ҩӹǹ�ѹ������ҧ�ҡἹ �֧�������ö���� */		 
	            	
	            	float daysCount = ((Float.parseFloat(leave_amount) == 0)?1:Float.parseFloat(leave_amount)); // ���ҧ���¤�ҵ�ͧ�� 1 ���� (���� ��. �Ҥ����ѹ �Ѻ�� 1 �ѹ)
	            	
	            	if(daysCount <= vDays.size()){ 
		            	for(int i = 0; i < daysCount ; i++){
			            	if(vDays.size() > 0) vDays.remove(0);
		            	}
			            days = vDays.size(); 
		            }else{ /* �ӹǹ�ѹ���� �ҡ���Ҩӹǹ�ѹ������ҧἹ��÷ӧҹ */
		            	//days = _ERROR;
		            	days = 0;
		            }
	            }else{ /* �ó�����ǧ˹������ͧ������ */
	            	/* ����͹Ҥ��ա����¹���͹����� */
		            days = vDays.size();
	            }
            }else{
            	days = 0;
            }
		}catch(Exception e){
			MyLog.error("!! Error : Can't find leave days from tabsent_nstda !!",e);
		}
		return days;
	}
	
	/* ��ʶҹ�Ҿ�ͧ������  */
	public boolean isSexValid(){
		boolean result = false;
		try {
			if(isLeaveLimitByBranch()){
            	if(initEventGrpBranch()){
            		if (grpRecBranch.getString("sex_type").equals("1") && !empRec.getString("sex").equals("1")) {			/* �к����繪�� �������˭ԧ */
    	                return true;
    	            } else if (grpRecBranch.getString("sex_type").equals("2") && !empRec.getString("sex").equals("2")) {	/* �к�����˭ԧ ������繪�� */
    	                return true;
    	            }
				}else{
					MyLog.error(" !! Can not find eventgrp : " + grpRec.getString("eventgrpid") + " by branch : " + this.empRec.getString("branch"));
				}
            }else{
	            if (grpRec.getString("sex_type").equals("1") && !empRec.getString("sex").equals("1")) {			/* �к����繪�� �������˭ԧ */
	                return true;
	            } else if (grpRec.getString("sex_type").equals("2") && !empRec.getString("sex").equals("2")) {	/* �к�����˭ԧ ������繪�� */
	                return true;
	            }
            }
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return result;
	}
	
	/* ����ҵ�ͧ������ǧ˹�� �������˹�������� */
	public boolean isRequireBeforeRequest(String date,String time){
		boolean result = false;
		try {
			CscCalendar csNow = new CscCalendar();
        	CscCalendar csStartLeave = new CscCalendar(date);
        	
			if(isLeaveLimitByBranch()){
            	if(initEventGrpBranch()){
            		if (csStartLeave.subForDay(csNow) < grpRecBranch.getFloat("datebeforerequest")) {
	            		return true;
	            	}
				}else{
					MyLog.error(" !! Can not find eventgrp : " + grpRec.getString("eventgrpid") + " by branch : " + this.empRec.getString("branch"));
				}
            }else{
				if (grpRec.getFloat("datebeforerequest") > 0) { 
	            	if (csStartLeave.subForDay(csNow) < grpRec.getFloat("datebeforerequest")) {
	            		return true;
	            	}
	            }
            }
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return result ;
	}
	
	/* ��Ǩ�ͺ������اҹ�������ö���������ѧ */
	public boolean isAllowForRequest(){
		try {
            CscCalendar csc = new CscCalendar(empRec.getString("firsthiredate"));  
            
            if(isLeaveLimitByBranch()){
            	if(initEventGrpBranch()){
            		if (csc.countDay(new CscCalendar()) < grpRecBranch.getInt("service_year")) {
    	        		return true;
    	            }
				}else{
					MyLog.error(" !! Can not find eventgrp : " + this.grpRec.getString("eventgrpid") + " by branch : " + this.empRec.getString("branch"));
				}
            }else{
	            if (csc.countDay(new CscCalendar()) < grpRec.getInt("service_year")) {
	        		return true;
	            }
            }
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return false;
	}
	
	/* �礨ӹǹ���駡�â��� */
	public boolean isOverLimitRequest(String eventgrp){
		boolean result = false;
		try {
			if(isLeaveLimitByBranch()){	/* ���Է�ԡ���ҵ���Ң� */
				if(initEventGrpBranch()){
					if (grpRecBranch.getInt("limit_times") >0 && grpRecBranch.getInt("limit_times") <= getAmountLeaveUsed(eventgrp)) {
		           		return true;
		            }
				}else{
					MyLog.error(" !! Can not find eventgrp : " + eventgrp + " by branch : " + this.empRec.getString("branch"));
				}
			}else{
				if (grpRec.getInt("limit_times") >0 && grpRec.getInt("limit_times") <= getAmountLeaveUsed(eventgrp)) {
	           		return true;
	            }
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return result;
	}
	
	public String getPrvEventDesc(){
		String desc = "";
		String event = "";
		try {
			if(isLeaveLimitByBranch()){	/* ���Է�ԡ���ҵ���Ң� */
				if(initEventGrpBranch()){
					 event = grpRecBranch.getString("privilege_event");
				}else{
					MyLog.error(" !! Can not find eventgrp : " + this.getEventGrp() + " by branch : " + this.empRec.getString("branch"));
				}
			}else{
				event = grpRec.getString("privilege_event");
			}
			
			if(!event.equals("")){
				DbRecord db = new InitialRecord(this.upf).getDbRecord("Meventgrp");
				db.setColumn("eventgrpid,tdesc,edesc");
				db.set("eventgrpid", event);
				db.set("companyid", this.upf.getComCode());
				if(db.search() == 1){
					if(((String)this.upf.get("lang")).equals("tha")){
						desc = db.getString("tdesc");
					}else{
						desc = db.getString("edesc");
					}
				}
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return desc;
	}
	
	public String getPrvEvent(){
		try {
			if(isLeaveLimitByBranch()){	/* ���Է�ԡ���ҵ���Ң� */
				if(initEventGrpBranch()){
					return grpRecBranch.getString("privilege_event");
				}else{
					MyLog.error(" !! Can not find eventgrp : " + this.getEventGrp() + " by branch : " + this.empRec.getString("branch"));
				}
			}else{
				return grpRec.getString("privilege_event");
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return "";
	}
	
	public String getEventDayType(){
		try {
			if(isLeaveLimitByBranch()){	/* ���Է�ԡ���ҵ���Ң� */
				if(initEventGrpBranch()){
					return grpRecBranch.getString("daytype");
				}else{
					MyLog.error(" !! Can not find eventgrp : " + this.getEventGrp() + " by branch : " + this.empRec.getString("branch"));
				}
			}else{
				return grpRec.getString("daytype");
			}
			
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return "";
	}
	
	/* �礡���ҷ������Ǣ�ͧ�ѹ ��Ҩ��繵�ͧ����������͹���һ�������� */
	public boolean isRequireEvent(){
		boolean result = false;
		try {
			String prv_event = getPrvEvent();
			
			if(prv_event != null && !prv_event.equals("")){
				ManageEmpLeaveStat mels = new ManageEmpLeaveStat(this.upf, empRec.getString("employeeid"), prv_event);
	            String remain = mels.getRemainLeave(prv_event);
	            
	            if(remain.equals("00:00:00")) {	/* ����ʹ������͡����������� */
	            	result = true;
	            }else{
	            	return false;
	            }
			}else{
				return true;
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return result;
	}
	
	public boolean isLeaveLimitByBranch(){
		boolean result = false;
		try {
			String stat =  (String) StaticConfig.getConfigCompany(this.upf, "TALVSET");
			if(stat != null && stat.equals("Y")){
				result = true;
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return result ;
	}
	
	/* �֧���Ϳ�Ŵ������¡������������������ѹ */
	private String getLeaveBranchField(){
		String fld = "";
		try {
			fld = (String) StaticConfig.getConfigCompany(this.upf, "TALVFD");
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return fld ;
	}
	
	public boolean initEventGrpBranch(){
		try {
			if(this.grpRecBranch == null || 
					(this.grpRec.getString("eventgrpid").equals(this.grpRecBranch.getString("eventgrp")) && 
							this.grpRec.getString("branch").equals(getFieldBranchValue()))) {
				
				grpRecBranch = new InitialRecord(this.upf).getDbRecord("Meventgrp1");
				grpRecBranch.setColumn("*");
				grpRecBranch.set("eventgrpid", this.getEventGrp());
				grpRecBranch.set("companyid", (String) this.upf.get("companyid"));
				grpRecBranch.set("branchid", this.empRec.getString(getLeaveBranchField()));
				
				if(grpRecBranch.search() == 1){
					return true;
				}else{
					return false;
				}
			}
		}catch(Exception e){
			MyLog.error(this,e);
			return false;
		}
		return true;
	}
	
	/* �֧�Է�ԡ����˹������ѹ */
	public int getLimitByBranch(){
		int rtn = 0;
		try {
			if(initEventGrpBranch()){
				if(grpRecBranch.getString("sharelimit_event").equals("")){
					if(getFixFeneralLeave().equals(this.getEventGrp())){	
						rtn = getFuneralLeaveByMfamily();
					}else{	/* �óջ��� ����ͧ�ӹdz�ҡ��㹤�ͺ���Ƿ��ʶҹ����ª��Ե */
						rtn = grpRecBranch.getInt("limit");
					}
				}else{
					if(getFixFeneralLeave().equals(this.getEventGrp())){	
						rtn = getFuneralLeaveByMfamily();
					}else{	/* �óջ��� ����ͧ�ӹdz�ҡ��㹤�ͺ���Ƿ��ʶҹ����ª��Ե */
						DbRecord db = new InitialRecord(this.upf).getDbRecord("Meventgrp1");
						db.setColumn("*");
						db.set("eventgrpid", grpRecBranch.getString("sharelimit_event"));
						db.set("companyid", (String) this.upf.get("companyid"));
						db.set("branchid", grpRecBranch.getString("branchid"));
						if(db.search() == 1){
							rtn = db.getInt("limit");
						}
					}
					
				}
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return rtn;
	}
	
	/* ��੾�� Nissan ����Ǩ�ͺ��㹤�ͺ���Ƿ���ʶҹ����ª��Ե��͹ ���͹��Ҥӹdz�� �Է�Է������ö���� */
	private String getFixFeneralLeave(){
		try {
			String code =  (String) StaticConfig.getConfigCompany(this.upf, "TAFNLCODE");	/* �����ҧҹȾ*/
			if(code != null && !code.equals("")){
				return code;
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return "";
	}
	
	/* ��੾�� Nissan ����Ǩ�ͺ��㹤�ͺ���Ƿ���ʶҹ����ª��Ե��͹ ���͹��Ҥӹdz�� �Է�Է������ö���� */
	private int getFuneralLeaveByMfamily(){
		int limit = 0;
		try {
			float hour_d = getHour_Day(this);
			limit = getCountPassAwayFamilay() * 5 ;	/* �Է�Է�����Ѻ��͹��ѧ� 120 �ѹ */
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return limit ;
	}
	
	/* �֧�ӹǹ��㹤�ͺ���Ƿ�����ª��Ե �ҷ����� ������͡੾�з�褹������ª��Ե����㹪�ǧ 120 ��͹��ѧ�ͧ���Ф� */
	private int getCountPassAwayFamilay(){
		int MAXPASTDATE = 120 ;	/* ��͹��ѧ� 120 �ѹ */
		int count = 0;
		try {
			DbInquiry inq = new InitialInquiry(this.upf).getDbInquiry("MEMPL_FAMILY");
			inq.setColumn("employeeid,companyid,relationid,line_no,pass_away_date");
			inq.setFilter("status = '0' and (pass_away_date is not null and pass_away_date != '') and employeeid = '"+ this.getEmployeeid() + "' and relationid in ('01','02','03','04','09','10','11','12','13','14','15') ");	/* ��������������ѹ��Ẻ��� � (99)*/
			inq.setOrderBy("pass_away_date desc");
			inq.refresh();
			
			CscCalendar cslast = null;
			while(inq.next()){
				if(cslast == null){ /* first loop */
					cslast = new CscCalendar(inq.getString("pass_away_date"));
					count++;
				}else {
					String psdate = inq.getString("pass_away_date");
					if(psdate != null && !psdate.equals("")){
						CscCalendar cur = new CscCalendar(psdate);
						
						if(!cur.equalsDate(cslast)){ /* ������ª��Ե�ѹ���ǡѺ����͹˹�� �ж��������������  */
							cslast.decDate(MAXPASTDATE);	/* �ѹ������ª��Ե����͹˹�� �����ѧ���ա 120 �ѹ */
							
							if(cur.afterEqualsDate(cslast)){	/* �֧੾�Ъ�ǧ�ѹ���ª��Ե����Թ 120 �ѹ�ҡ���á�����ѹ���Ѩ�غѹ*/
								cslast = new CscCalendar(psdate);
								count++;
							}
						}
					}
				}
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return count ;
	}
	
	/* ���ѹ������ª��Ե�ͧ��㹤�ͺ��������ش */
	private CscCalendar getLastPassAwayMfamily(){
		CscCalendar cslast = null;
		int MAXPASTDATE = 120 ;	/* ��͹��ѧ� 120 �ѹ */
		int count = 0;
		try {
			DbInquiry inq = new InitialInquiry(this.upf).getDbInquiry("MEMPL_FAMILY");
			inq.setColumn("employeeid,companyid,relationid,line_no,pass_away_date");
			inq.setFilter("status = '0' and (pass_away_date is not null and pass_away_date != '') and employeeid = '"+ this.getEmployeeid() + "' and relationid in ('01','02','03','04','09','10','11','12','13','14','15') ");	/* ��������������ѹ��Ẻ��� � (99)*/
			inq.setOrderBy("pass_away_date desc");
			inq.refresh();
			
			while(inq.next()){
				if(cslast == null){ /* first loop */
					cslast = new CscCalendar(inq.getString("pass_away_date"));
					count++;
				}else{
					String psdate = inq.getString("pass_away_date");
					if(psdate != null && !psdate.equals("")){
						CscCalendar cur = new CscCalendar(psdate);
				
						if(!cur.equalsDate(cslast)){ /* ������ª��Ե�ѹ���ǡѺ����͹˹�� �ж��������������  */
							cslast.decDate(MAXPASTDATE);	/* �ѹ������ª��Ե����͹˹�� �����ѧ���ա 120 �ѹ */
							
							if(cur.afterEqualsDate(cslast)){	/* �֧੾�Ъ�ǧ�ѹ���ª��Ե����Թ 120 �ѹ�ҡ���á�����ѹ���Ѩ�غѹ*/
								cslast = new CscCalendar(inq.getString("pass_away_date"));
								count++;
							}
						}
					}
				}
			}
			
			if(count == 0) cslast = new CscCalendar();	/* ����������ª��Ե */
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return cslast ;			
	}
	
	/* �֧�ӹǹ�ѹ�����Ҭһ��Ԩ����� �觤�ҡ�Ѻ�繹ҷ� */
	private float getHisFuneralLeave(){
		CscTime sumlv = new CscTime();
		try {
			CscCalendar lastdate = getLastPassAwayMfamily();	/* �ѹ������ª��Ե����ش�ͧ��㹤�ͺ����*/
			
			DbInquiry inq = new InitialInquiry(this.upf).getDbInquiry("Tleave_summary");
			inq.setColumn("employeeid,companyid,dateid,m_lv,hour_s");
			inq.setFilter("employeeid = '" + this.getEmployeeid() + "' and dateid >= '" + lastdate.getYYYYMMDD() + "' and lv_type = '"+ this.getEventGrp() +"' ");	
			inq.setOrderBy("dateid desc");
			inq.refresh();
			
			while(inq.next()){
				sumlv.add(Float.parseFloat(inq.getString("m_lv")));
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return sumlv.getFloat();
	}
	
	/* �֧�Է�ԡ����˹����� ��. */
	public String getLimitHoursByBranch(){
		String rtn = "00:00";
		DecimalFormat df = new DecimalFormat("00.00");
		try {
			if(initEventGrpBranch()){
				rtn = df.format(Double.parseDouble(grpRecBranch.getString("limit_hours"))).replace(".", ":");
			}
		}catch(Exception e){
			MyLog.error("Time output is not in format ##:##, system will change value to 00:00 automatically !! ");
			//MyLog.error(this,e);
		}
		return rtn;
	}
	
	public int getLimitAmountByBranch(){
		int rtn = 0;
		try {
			if(initEventGrpBranch()){
				rtn = grpRecBranch.getInt("limit_times");
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return rtn;
	}
	
	/* ���͡��Ŵ��ҢҨҡ ��Ŵ� branch ���ͨҡ branchid � ���ҧ memployee */
	private String getFieldBranchValue(){
		String fld = "";
		try {
			fld =  (String) StaticConfig.getConfigCompany(this.upf, "TALVFD");
			
			if(fld != null && !fld.equals("")){
				this.empRec.getString(fld);
			}else{
				this.empRec.getString("branch");
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return fld ;
	}
	
	/* �֧���ʻѴ��� ��. �� */
	public String getRoundingCode(){
		try {
			if(isLeaveLimitByBranch()){	/* ���Է�ԡ���ҵ���Ң� */
				if(initEventGrpBranch()){
					return grpRecBranch.getString("leaverounding");
				}else{
					MyLog.error(" !! Can not find eventgrp : " + this.getEventGrp() + " by branch : " + this.empRec.getString("branch"));
				}
			}else{
				return grpRec.getString("leaverounding");
			}
		}catch(Exception e){
			MyLog.error("Rounding not found for eventgrp " + this.getEventGrp());
			MyLog.error(this,e);
		}
		return "";
	}
	
	/* �Ѵ��� ��. �� */
	public float getRoudingValue(double value) {
		float result = (float) value;
		try {
			String code = getRoundingCode();
			
			if(!code.equals("")){
				RoundingTime rt = new RoundingTime(code, value);
				rt.setUProfile(this.upf);
				result = (float) rt.getRounding();		
			}
		} catch (Exception e) {
			MyLog.error(this, e);			
		}
		return result;
	}
	
	/* �֧�������ʹ�������ѡ��͹ ��ǧ�������ö���͡¡����  */
	public String getAnnualLeaveOnV0Period(String eventgrp){
		String lv = "00:00:00";
		try {
            CscTime lv_hour = new CscTime();
			
			DbInquiry leave = new InitialInquiry(this.upf).getDbInquiry("TLEAVE_SUMMARY");
			leave.setColumn("*");
			leave.setFilter("employeeid = '" + this.empRec.getString("employeeid") 
					+ "' and dateid between '" + normalLeaveStart.getYYYYMMDD() 
					+ "' and '"+ getVacationLast().getYYYYMMDD() +"'" 
					+ " and lv_type = '" + eventgrp + "'");
			leave.refresh();
			
			used_count = leave.recCount();
			while(leave.next()){
				lv_hour.add(Float.parseFloat(leave.getString("m_lv")));
			}
			
			DHMConvert dhm = new DHMConvert();
			float hour_d = getHour_Day(this);
			int minV0 = dhm.DHMToMin(this.empRec.getString("vacation0"), Float.toString(hour_d));
			int usedOnV0 = (lv_hour.getHour() * 60) + lv_hour.getMinute();
			
			// if used on v0 period less than v0 then set v0 = used 
			if(usedOnV0 < minV0){
				dhm = new DHMConvert(lv_hour.getFloat(), hour_d);
				lv = dhm.parseDHM();
			}else{
				lv = this.empRec.getString("vacation0");
			}
			
			
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return lv;
	}
	
	/* get date config from mconfig */
	/* 
	 * ������ҧ 
	 * �է�����ҳ 01-11 ---------------------------- 31-10
	 * �ѹ������ 04-12-2012 (����ǧ˹�� �է�����ҳ˹��)
	 * ��˹����� ����͹�Ѻ�ѹ������  01-11-2012 ----------------------- 31-10-2012
	 * 		�ѹ�������ش�է�����ҳ���¡�����������ʴ�����繤������ ��˹������������ 01-11-2011 ------------------- 31-10-2012
	 * ���º��º�ѹ����������㹪�ǧ�է�����ҳ������������ ��� �� 04-12-2012 �ҡ���� 31-10-2012 �ѧ����ͧ��Ѻ�է�����ҳ����ѹ������
	 * 		�� 01-11-2012 -------------------- 31-10-2013 �����������ѹ�����������Ǩ�����㹻����ǡѺ�ѹ������
	 */
	private void initialDateConfig(ManageEmpLeaveStat mel){
		try {
			/* �ҷ���� */
			normalLeaveStart = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1001"));	/* �ѹ���������鹻է�����ҳ */
            normalLeaveEnd = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1002"));	/* �ѹ�������ش�է�����ҳ */
			
            /* �Ҿѡ��͹ */
            vacationStart = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1003"));	/* �ѹ���������鹻է�����ҳ */
            vacationEnd = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1004"));		/* �ѹ�������ش�է�����ҳ */
            
            if(reqdate_st != null){
	            /* ����Ҫ�ǧ�է�����ҳ��Ẻ������� ���� ����ش���㹻����ǡѹ �����˹�˹��»��ѹ�����������������ش���١��ͧ */
	            normalLeaveStart.setYear(this.reqdate_st.getYear());
	            normalLeaveEnd.setYear(this.reqdate_st.getYear());
	            
	            vacationStart.setYear(this.reqdate_st.getYear());
	            vacationEnd.setYear(this.reqdate_st.getYear());
            }else{
            	this.reqdate_st = new CscCalendar(normalLeaveStart.getYYYYMMDD());
            	this.reqdate_en = new CscCalendar(normalLeaveEnd.getYYYYMMDD());
            }
            
            /* ��ҡ�˹��բͧ�ѹ������ ���Ѻ �ѹ���������� �������ش �ͧ�է�����ҳ �����ѹ�������ش���¡��� �ѹ�����������ʴ���һէ�����ҳ��Ẻ������� */
            if(normalLeaveEnd.beforeDate(normalLeaveStart)){
            	normalLeaveStart.decYear(1);
            }
            
            /* ����ѹ������ �繡���Ңͧ�նѴ�����Ѻ�է�����ҳ���ç�Ѻ�ѹ������ */
        	if(this.reqdate_st.afterDate(normalLeaveEnd)){
        		normalLeaveStart.incYear(1);
        		normalLeaveEnd.incYear(1);
        	}
            
            if(vacationEnd.beforeDate(vacationStart)){
            	vacationStart.decYear(1);
            }
            
            /* ����ѹ������ �繡���Ңͧ�նѴ�����Ѻ�է�����ҳ���ç�Ѻ�ѹ������ */
        	if(this.reqdate_st.afterDate(vacationEnd)){
        		vacationStart.incYear(1);
        		vacationEnd.incYear(1);
        	}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	/* check today is in budget period */
	private boolean isCurDateInCurYear(){
		try {
			CscCalendar today = new CscCalendar();
			if(today.afterEqualsDate(normalLeaveStart) && today.beforeEqualsDate(normalLeaveEnd)){
				return true;
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return false;
	}
	
	/* �礡������ ��. ��鹵�� ��ҹ��¡��ҡ�˹��������Ң�鹵�� */
	public float chkMinHourReq(float hour){
		try {
			if(grpRec.getFloat("min_limit_hours") > hour){
				return grpRec.getFloat("min_limit_hours") ;
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return hour ;
	}
	
	/* ��˹��ѹ������ �����ѹ��� �����ӹdz���Է�ԡ�����ҡ���� 1 �ѹ */
	public void setRequestDate(String st, String en){
		try {
			reqdate_st = new CscCalendar(st);
			reqdate_en = new CscCalendar(en);
			
			initialDateConfig(this);	/* ��˹��ѹ���������� ����ش �է�����ҳ ��Ѻ����¹����ѹ������ */
		}catch(Exception e){
			MyLog.error(this,e);
		}
	}
	
	/* ��˹��ѹ������ �����ѹ��� �����ӹdz���Է�ԡ���� 1 �ѹ */
	public void setRequestDate(String date){
		try {
			reqdate_st = new CscCalendar(date);
			reqdate_en = new CscCalendar(date);
			
			initialDateConfig(this);	/* ��˹��ѹ���������� ����ش �է�����ҳ ��Ѻ����¹����ѹ������ */
		}catch(Exception e){
			MyLog.error(this,e);
		}
	}
	
	/* ��˹��ѹ������ �����ѹ��� �����ӹdz���Է�ԡ���� 1 �ѹ */
	public void setRequestDate(){
		reqdate_st = null;
		reqdate_en = null;
		
		initialDateConfig(this);	/* ��˹��ѹ���������� ����ش �է�����ҳ ��Ѻ����¹����ѹ������ */
	}
	
	private void initialUsed(){
		CscTime lv_hour = new CscTime();
		try {
			DbInquiry leave = new InitialInquiry(this.upf).getDbInquiry("TLEAVE_SUMMARY");
			leave.setColumn("*");
			
			String filter = "employeeid = '" + this.empRec.getString("employeeid") 
					+ "' and dateid between '" + getPeriodStart().getYYYYMMDD() 
					+ "' and '"+ getPeriodEnd().getYYYYMMDD() +"'" 
					+ " and m_lv > 0 and lv_type != ' '";
					if(this.absentProp!=null && !this.absentProp.getString("absentid").equals("")){
						filter+= " and docid != '"+this.absentProp.getString("absentid")+"' ";
					}
			
			leave.setFilter(filter);
			leave.refresh();
			
			HashMap hmdocid = new HashMap();
			while(leave.next()){
				if(hmLvType.containsKey(leave.getString("lv_type"))){
					LeaveStatProp lsp = (LeaveStatProp) hmLvType.get(leave.getString("lv_type"));
					lsp.addUsed(leave.getString("m_lv"));
					
					if(!hmdocid.containsKey(leave.getString("docid"))){
						lsp.addUsedCount();
						hmdocid.put(leave.getString("docid"),"");					
					}
				}
			}

		}catch(Exception e){
			MyLog.error(this,e);
		}
	}
	
	private CscCalendar getPeriodStart(){
		try {
			if(reqdate_st != null){
				return reqdate_st ;
			}else{
				return normalLeaveStart ;
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return null ;
	}
	
	private CscCalendar getPeriodEnd(){
		try {
			if(reqdate_en != null){
				return reqdate_en ;
			}else{
				return normalLeaveEnd ;
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return null ;
	}
	
	/* �ó���Ẻ �ѡ��͹ �������¹�ҨѺ�ҡ Approve Date */
	private boolean checkapprove_date(){
		 boolean res = false;
		 String approve_date = "";
		 int day = 0;
		 String leavedate = "";
		 try {
			 if(empRec != null){
				 approve_date = empRec.getString("approve_date");
			 }else{
				 DbRecord db = new InitialRecord(this.upf).getDbRecord("Memployee");
				 db.setColumn("employeeid,companyid,approve_date");
				 db.set("employeeid", this.employeeid);
				 if(db.search() == 1){
					 approve_date = db.getString("approve_date");
				 }
			 }
			 
			 if(this.absentProp != null){
				leavedate = this.absentProp.getString("start_date");
			 }
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		 
		CscCalendar leave_date = new CscCalendar(leavedate);
		CscCalendar appr_date = new CscCalendar(approve_date);
		day = leave_date.subForDay(appr_date);
		if(day >= 0){
			res = true;
		}
		return res;
	}
	
	private String getLeaveInAdv(LeaveStatProp lsp){
		String rtn = "00:00:00" ;
		try {
			if(lsp.getLvData().getString("limitformula").length() > 0){
				Interpreter in = new Interpreter();
				in.set("vacClass", this);
				in.set("todaydate", new CscCalendar());	/* �ѹ���Ѩ�غѹ�� CscCalendar */
				in.set("hour_d", getHour_Day(this));
				in.set("util", new Ttime_current1());	/* ���ҧ ttime_current1 ������ҹ getRounding method */
				in.set("DHMConv", new DHMConvert()); 
	
				in.eval(lsp.getLvData().getString("limitformula"));	/* ��˹�����ٵ÷���ͧ��� compile */
				
				rtn = String.valueOf(in.get("result"));	/* �֧���Ѿ����ѧ��÷�� compile �ٵ� */
			}else{
				rtn = lsp.getLvData().getString("limit") + ":00:00";
			}

		}catch(Exception e){
			MyLog.error(this,e);
		}
		return rtn ;
	}
	
	/* �ӹdz�Է�����ء���� �������֧�ҡ MEMPLOYEE.VACATION1*/
	public String CalAnnualLeaveNextYear(int caldate, int calmonth){
		try {
			CscCalendar today = new CscCalendar();
			CscCalendar csc_cald = new CscCalendar(caldate + "-" + calmonth + "-" + (today.getYear()+1));
			
			/* ��˹� param */
			CalculateVacation_New cn = new CalculateVacation_New();
			cn.setUProfile(this.upf);
			cn.setParamData("calActual","true");
			if(absentProp != null){
				cn.setParamData("filterProcess", "employeeid = '" + absentProp.getString("employeeid") + "'");
			}else{
				cn.setParamData("filterProcess", "employeeid = '" + this.empRec.getString("employeeid") + "'");
			}

			/* ���ѹ����ش ����� ���ѹ�ӹdz���اҹ */
			cn.setParamData("caldate", csc_cald.getYYYYMMDD());
			cn.setParamData("employeeSelect", this.employeeid + "#");
			cn.isSave(false);	/* ����ͧ�ѹ�֡ŧ���ҧ Memployee */
			cn.calVirtualVacation1();
			
			return cn.getDataFromEmpProp("new_vacation1");
			
		}catch(Exception e){
			MyLog.error(this,e);
		}
		
		return (this.empRec.getString("vacation1")!=null&&!this.empRec.getString("vacation1").equals(""))?
				this.empRec.getString("vacation1"):"00:00:00";
	}
	
	private String deductReqAnnualInAdvance(LeaveStatProp lsp, String vac1){
		String rtn = vac1 ;
		try {
			DHMConvert dhm = new DHMConvert();
			int min_vac = dhm.DHMToMin(vac1, lsp.getHourd());
			
			int min_borrow_used = getAnnualInAdvance();
			
			if(min_vac > min_borrow_used){
				rtn = dhm.MinToDHM(min_vac - min_borrow_used, lsp.getHourd());
			}else{ /* ���������� */
				rtn = "00:00:00" ;
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return rtn ;
	}
	
	private int getAnnualInAdvance(){
		int rtn = 0;
		String BTYPE = "A";
		try {
			/* �������ʻ������ѹ�������㹡��������ǧ˹�һէ�����ҳ */
			DbInquiry inqbtype = null ;
			if(isLeaveLimitByBranch()){
				inqbtype = new InitialInquiry(this.upf).getDbInquiry("meventgrp1");
			}else{
				inqbtype = new InitialInquiry(this.upf).getDbInquiry("meventgrp");
			}
			
			inqbtype.setColumn("eventgrpid");
			inqbtype.setFilter("daytype = '" + BTYPE + "'");
			inqbtype.refresh();
			
			StringBuffer sb = new StringBuffer();
			while(inqbtype.next()){
				if(sb.length()>0) sb.append(",");
				
				sb.append("'").append(inqbtype.getString("eventgrpid")).append("'");
			}
			
			/* �����һ��������������ǧ˹�һէ�����ҳ �ա�͹˹�� */
			if(sb.length() > 0){
				DbInquiry inq = new InitialInquiry(this.upf).getDbInquiry("Tleave_summary");
				inq.setColumn("employeeid,companyid,m_lv,lv_type");
				
				CscCalendar cscLeaveStart = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1001"));
	            CscCalendar cscLeaveEnd = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1002"));
	            
	            String emp = this.empRec.getString("employeeid") ;
	            CscCalendar st = new CscCalendar();
				if(this.absentProp != null){
					st = new CscCalendar(this.absentProp.getString("start_date"));
					st.decYear(1);
				}
				
				if(st.afterEqualsDate(cscLeaveStart) && st.beforeEqualsDate(cscLeaveEnd)){
					cscLeaveStart.decYear(1);
					cscLeaveEnd.decYear(1);
				}else if(st.beforeDate(cscLeaveStart)){ /* ��͹��ѧ�է�����ҳ�Ѩ�غѹ ������ 2 �� */
					cscLeaveStart.decYear(2);
					cscLeaveEnd.decYear(2);
				}
				inq.setFilter("employeeid = '" + emp + "' and dateid between '" + cscLeaveStart.getYYYYMMDD() + "' and '"
						+ cscLeaveEnd.getYYYYMMDD() + "' and lv_type in (" + sb.toString() + ")");
				
				inq.refresh();
				CscTime ct = new CscTime();
				while(inq.next()){
					ct.add(Float.parseFloat(inq.getString("m_lv")));
				}
				
				DHMConvert dhm = new DHMConvert();
				rtn = dhm.timeToMin(ct.getFloat());
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return rtn ;
	}
	
	public String getAnnualInAdvanceDHM(){
		String rtn = "00:00:00";
		String BTYPE = "A";
		try {
			/* �������ʻ������ѹ�������㹡��������ǧ˹�һէ�����ҳ */
			DbInquiry inqbtype = null ;
			if(isLeaveLimitByBranch()){
				inqbtype = new InitialInquiry(this.upf).getDbInquiry("meventgrp1");
			}else{
				inqbtype = new InitialInquiry(this.upf).getDbInquiry("meventgrp");
			}
			
			inqbtype.setColumn("eventgrpid");
			inqbtype.setFilter("daytype = '" + BTYPE + "'");
			inqbtype.refresh();
			
			StringBuffer sb = new StringBuffer();
			while(inqbtype.next()){
				if(sb.length()>0) sb.append(",");
				
				sb.append("'").append(inqbtype.getString("eventgrpid")).append("'");
			}
			
			/* �����һ��������������ǧ˹�һէ�����ҳ �ա�͹˹�� */
			if(sb.length() > 0){
				DbInquiry inq = new InitialInquiry(this.upf).getDbInquiry("Tleave_summary");
				inq.setColumn("employeeid,companyid,m_lv,lv_type");
				
				CscCalendar cscLeaveStart = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1001"));
	            CscCalendar cscLeaveEnd = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1002"));
	            
	            String emp = this.empRec.getString("employeeid") ;
	            CscCalendar st = new CscCalendar();
				if(this.absentProp != null){
					st = new CscCalendar(this.absentProp.getString("start_date"));
					//st.decYear(1);
				}
				
				if(st.afterEqualsDate(cscLeaveStart) && st.beforeEqualsDate(cscLeaveEnd)){
					cscLeaveStart.decYear(1);
					cscLeaveEnd.decYear(1);
				}else if(st.beforeDate(cscLeaveStart)){ /* ��͹��ѧ�է�����ҳ�Ѩ�غѹ ������ 2 �� */
					cscLeaveStart.decYear(2);
					cscLeaveEnd.decYear(2);
				}
				inq.setFilter("employeeid = '" + emp + "' and dateid between '" + cscLeaveStart.getYYYYMMDD() + "' and '"
						+ cscLeaveEnd.getYYYYMMDD() + "' and lv_type in (" + sb.toString() + ")");
				
				inq.refresh();
				CscTime ct = new CscTime();
				while(inq.next()){
					ct.add(Float.parseFloat(inq.getString("m_lv")));
				}
				
				DHMConvert dhm = new DHMConvert();
				rtn = dhm.MinToDHM(dhm.timeToMin(ct.getFloat()),getHour_Day(this));
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return rtn ;
	}
	
	/* �֧�������ʹ�������ͧ�նѴ仵�������� */
	public String getLeaveNextUsed(String eventgrp, DbRecord absentprop){
		String lv = "00:00:00";
		try {
			used_count = 0;
			
			CscCalendar cscLeaveStart = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1001"));
            CscCalendar cscLeaveEnd = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1002"));
            CscCalendar cscVacationStart = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1003"));
            CscCalendar cscVacationEnd = new CscCalendar((String) StaticConfig.getConfigCompany(this.upf, "TA1004"));
            
            CscTime lv_hour = new CscTime();
            
            LeaveStatProp lsp = null ;
            if(hmLvType.containsKey(eventgrp)){
            	lsp = (LeaveStatProp) hmLvType.get(eventgrp);
            	grpRec = lsp.getLvData() ;
            	
            	if(isClearStatByMonth(lsp)){	/* ����������ʹ�����ء��͹ �����੾�Ъ�ǧ��͹������ */
                	CscCalendar curmonth_st = new CscCalendar(absentprop.getString("start_date"));
                	CscCalendar curmonth_en = new CscCalendar(absentprop.getString("start_date"));
                	curmonth_st.setDate(1); /* ��������ѹ��� 1 */
                	curmonth_en.setDate(curmonth_en.getEndDateOfMonth());
                	
                	cscLeaveStart = new CscCalendar(curmonth_st.getYYYYMMDD());	/* ��˹��ѹ������������͹����᷹ */
                	cscLeaveEnd = new CscCalendar(curmonth_en.getYYYYMMDD());	/* ��˹��ѹ�������ش�ͧ��͹����᷹ */
                }
            	
            	/* ����������� */
                String eventlist = "";
                if(grpRec.getField("sharelimit_event") != null && !grpRec.getString("sharelimit_event").equals("")){
                	eventlist = "(";
                	eventlist += "lv_type in ('" + eventgrp + "','" + grpRec.getString("sharelimit_event") + "') ";
                	eventlist += " OR lv_type in (select eventgrpid from " + grpRec.getActualName() + " where sharelimit_event in ('" + eventgrp + "','" + grpRec.getString("sharelimit_event") + "'))" ;
                	eventlist += ")";
                }else{
                	eventlist += "lv_type = '" + eventgrp + "'";
                }
                
                cscLeaveStart.incYear(1);
                cscLeaveEnd.incYear(1);
    			
    			DbInquiry leave = new InitialInquiry(this.upf).getDbInquiry("TLEAVE_SUMMARY");
    			leave.setColumn("*");
    			String filter = eventlist + " and employeeid = '" + this.empRec.getString("employeeid") 
    					+ "' and dateid between '" + cscLeaveStart.getYYYYMMDD() 
    					+ "' and '"+ cscLeaveEnd.getYYYYMMDD() +"'" ;
    			
    			if(!absentprop.getString("absentid").equals("")){ /* �������Ţ����͡��÷���˹����͡���¡��� �����Ҥӹdz�ʹ���  */
    				filter += " and docid != '" + absentprop.getString("absentid")+ "'";
    			}
    			
    			leave.setFilter(filter);
    			leave.refresh();
    			
    			String docid = "";
    			while(leave.next()){
    				lv_hour.add(Float.parseFloat(leave.getString("m_lv")));
    				
    				if(!docid.equals(leave.getString("docid"))){
    					docid = leave.getString("docid");
    					used_count++;
    				}
    			}
    			
    			/* �ó��Ҭһ��Ԩ ����˹�������� mconfig ��� �ʴ���ҵ�ͧ������ӹdz����ӹǹ������ª��Ե��ԧ  */
    			if(getFixFeneralLeave().equals(grpRec.getString("eventgrpid"))){
    				lv_hour = new CscTime();
    				lv_hour.add(this.getHisFuneralLeave());
    			}
    			
    			DHMConvert dhm = new DHMConvert(lv_hour.getFloat(), getHour_Day(this));
    			lv = dhm.parseDHM();
            }
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return lv;
	}
	
	/* �ʹ������͡����㹻նѴ� */
	public String getRemainNextLeave(String eventgrp){
		String remain = "00:00:00";
		try {
			DHMConvert dhm = new DHMConvert();
			int limit = 0;
			int used  = 0;
			float hourd = getHour_Day(this) ;

			limit = dhm.DHMToMin(getLimitLeave(eventgrp),Float.toString(hourd));
			used  = dhm.DHMToMin(getLeaveNextUsed(eventgrp, this.absentProp),Float.toString(hourd));

			if(limit >= used){
				remain = dhm.MinToDHM((limit - used),hourd);
			}else{
				remain = dhm.MinToDHM((used - limit),hourd);
				remain = "-" + remain;
				MyLog.debug("!! Leave used is greater than limit, result will be negative value !! ");
			}
		}catch(Exception e){
			MyLog.error(this,e);
		}
		return remain;
	}
}