/*
* Aipo is a groupware program developed by TOWN, Inc.
* Copyright (C) 2004-2015 TOWN, Inc.
* http://www.aipo.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.aimluck.eip.timecard;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import com.aimluck.commons.field.ALDateField;
import com.aimluck.commons.field.ALNumberField;
import com.aimluck.commons.field.ALStringField;
import com.aimluck.eip.cayenne.om.portlet.EipTTimecardSettings;
import com.aimluck.eip.common.ALData;
import com.aimluck.eip.orm.Database;
import com.aimluck.eip.orm.query.SelectQuery;
import com.aimluck.eip.timecard.util.TimecardUtils;
/**
* 一日分のタイムカード(出勤・退勤の履歴)を保持する。 一日ごとの勤務時間・残業時間などを計算し、その結果を保持する。
*
*
*/
public class TimecardSummaryResultData implements ALData {
private ALDateField date = null;
private List<TimecardResultData> list = null;
private ALNumberField shugyo = null;
private ALNumberField jikannai = null;
private ALNumberField jikannai1 = null;
private ALNumberField jikannai2 = null;
private ALNumberField zangyo = null;
private ALNumberField zangyo1 = null;
private ALNumberField zangyo2 = null;
private ALNumberField kyushutsu = null;
private ALStringField chikoku = null;
private ALStringField sotai = null;
/**
*
*/
@Override
public void initField() {
date = new ALDateField();
date.setValue(new Date());
list = new ArrayList<TimecardResultData>();
shugyo = new ALNumberField(0);
jikannai = new ALNumberField(0);
jikannai1 = new ALNumberField(0);
jikannai2 = new ALNumberField(0);
zangyo = new ALNumberField(0);
zangyo1 = new ALNumberField(0);
zangyo2 = new ALNumberField(0);
kyushutsu = new ALNumberField(0);
chikoku = new ALStringField();
sotai = new ALStringField();
}
/**
*
* @param date
*/
public void setDate(Date date) {
this.date.setValue(date);
}
/**
* @return date
*/
public ALDateField getDate() {
return date;
}
/**
*
* @return
*/
public ALNumberField getKyushutsu() {
return kyushutsu;
}
/**
*
* @param kyushutsu
*/
public void setKyushutsu(ALNumberField kyushutsu) {
this.kyushutsu = kyushutsu;
}
/**
*
* @return
*/
public ALNumberField getShugyo() {
return shugyo;
}
/**
*
* @return
*/
public ALStringField getShugyoStr() {
return new ALStringField(minuteToHour(shugyo.getValue()));
}
/**
*
* @param shugyo
*/
public void setShugyo(ALNumberField shugyo) {
this.shugyo = shugyo;
}
/**
*
* @return
*/
public ALNumberField getJikannai() {
return jikannai;
}
/**
*
* @return
*/
public ALStringField getJikannaiStr() {
return new ALStringField(minuteToHour(jikannai.getValue()));
}
/**
*
* @return
*/
public ALNumberField getJikannai1() {
return jikannai1;
}
/**
*
* @return
*/
public ALStringField getJikannai1Str() {
return new ALStringField(minuteToHour(jikannai1.getValue()));
}
/**
*
* @return
*/
public ALNumberField getJikannai2() {
return jikannai2;
}
/**
*
* @return
*/
public ALStringField getJikannai2Str() {
return new ALStringField(minuteToHour(jikannai2.getValue()));
}
/**
*
* @return
*/
public ALNumberField getZangyo() {
return zangyo;
}
/**
*
* @return
*/
public ALStringField getZangyoStr() {
return new ALStringField(minuteToHour(zangyo.getValue()));
}
/**
*
* @param zangyo
*/
public void setZangyo(ALNumberField zangyo) {
this.zangyo = zangyo;
}
/**
*
* @return
*/
public ALNumberField getZangyo1() {
return zangyo1;
}
/**
*
* @return
*/
public ALStringField getZangyo1Str() {
return new ALStringField(minuteToHour(zangyo1.getValue()));
}
/**
*
* @return
*/
public ALNumberField getZangyo2() {
return zangyo2;
}
/**
*
* @return
*/
public ALStringField getZangyo2Str() {
return new ALStringField(minuteToHour(zangyo2.getValue()));
}
/**
*
* @return
*/
public ALStringField getChikoku() {
return chikoku;
}
/**
*
* @return
*/
public ALStringField getSotai() {
return sotai;
}
/**
*
* @param minute
* @return
*/
private String minuteToHour(long minute) {
BigDecimal decimal = new BigDecimal(minute / 60.0);
DecimalFormat dformat = new DecimalFormat("##.#");
String str =
dformat.format(decimal.setScale(1, BigDecimal.ROUND_FLOOR).doubleValue());
return str;
}
/**
*
* @return
*/
public String getDateStr() {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日(EE)");
return sdf.format(date.getValue().getDate());
} catch (Exception e) {
return "";
}
}
/**
*
* @return
*/
public List<TimecardResultData> getList() {
return list;
}
/**
*
* @return
*/
public List<TimecardResultData> getViewList() {
List<TimecardResultData> viewlist = new ArrayList<TimecardResultData>();
TimecardResultData rd = null;
int size = list.size();
for (int i = 0; i < size; i++) {
rd = list.get(i);
if (!TimecardUtils.WORK_FLG_DUMMY.equals(rd.getWorkFlag().getValue())) {
viewlist.add(rd);
}
}
return viewlist;
}
/**
*
* @param rd
*/
public void addTimecardResultData(TimecardResultData rd) {
list.add(rd);
}
/**
* 就業時間、残業時間などを計算する。
*
*/
public void calc() {
try {
// 勤務時間設定データを取得
EipTTimecardSettings settings = loadEipTTimecardSettings();
// カレンダーオブジェクトを初期化
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, Integer.parseInt(date.getYear()));
cal.set(Calendar.MONTH, Integer.parseInt(date.getMonth()) - 1);
cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(date.getDay()));
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Date startDate = cal.getTime();
Date endDate = null;
cal.set(Calendar.HOUR_OF_DAY, settings.getStartHour());
cal.set(Calendar.MINUTE, settings.getStartMinute());
Date kinmuStartDate = cal.getTime();
cal.set(Calendar.HOUR_OF_DAY, settings.getEndHour());
cal.set(Calendar.MINUTE, settings.getEndMinute());
Date kinmuEndDate = cal.getTime();
List<TimecardResultData> tempList = new ArrayList<TimecardResultData>();
boolean startflg = false;
for (TimecardResultData rd : this.list) {
if (TimecardUtils.WORK_FLG_ON.equals(rd.getWorkFlag().getValue())) {
startDate = rd.getWorkDate().getValue();
// 出勤データが連続するときは、退勤データを挿入
if (startflg == true) {
tempList.add(createTimecardResultData(
startDate,
TimecardUtils.WORK_FLG_OFF));
}
tempList.add(rd);
startflg = true;
} else if (TimecardUtils.WORK_FLG_OFF.equals(rd
.getWorkFlag()
.getValue())) {
// 日の最初が出勤ではないときは、0:00のデータを追加する
// 退勤データが連続するときは、出勤データを挿入
if (startflg == false) {
tempList.add(createTimecardResultData(
startDate,
TimecardUtils.WORK_FLG_ON));
}
endDate = rd.getWorkDate().getValue();
// 勤務時間内外の区切るを挿入
if (kinmuStartDate.after(startDate) && kinmuStartDate.before(endDate)) {
tempList.add(createTimecardResultData(
kinmuStartDate,
TimecardUtils.WORK_FLG_OFF));
tempList.add(createTimecardResultData(
kinmuStartDate,
TimecardUtils.WORK_FLG_ON));
}
if (kinmuEndDate.after(startDate) && kinmuEndDate.before(endDate)) {
tempList.add(createTimecardResultData(
kinmuEndDate,
TimecardUtils.WORK_FLG_OFF));
tempList.add(createTimecardResultData(
kinmuEndDate,
TimecardUtils.WORK_FLG_ON));
}
tempList.add(rd);
startDate = endDate;
startflg = false;
}
}
// 最後に退勤していない場合は、0:00退勤のデータを追加する。
if (startflg) {
cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH) + 1);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
endDate = cal.getTime();
// 勤務時間内外の区別をつける
if (kinmuStartDate.after(startDate) && kinmuStartDate.before(endDate)) {
tempList.add(createTimecardResultData(
kinmuStartDate,
TimecardUtils.WORK_FLG_OFF));
tempList.add(createTimecardResultData(
kinmuStartDate,
TimecardUtils.WORK_FLG_ON));
}
if (kinmuEndDate.after(startDate) && kinmuEndDate.before(endDate)) {
tempList.add(createTimecardResultData(
kinmuEndDate,
TimecardUtils.WORK_FLG_OFF));
tempList.add(createTimecardResultData(
kinmuEndDate,
TimecardUtils.WORK_FLG_ON));
}
TimecardResultData rd = new TimecardResultData();
rd.initField();
rd.setWorkDate(endDate);
rd.setWorkFlag(TimecardUtils.WORK_FLG_OFF);
tempList.add(rd);
}
// 整列されたデータを順に見て、就業時間などを数える
long shugyo_temp = 0;
long jikannai_temp = 0;
long zangyo_temp = 0;
boolean iszangyo = false;
for (TimecardResultData rd : tempList) {
if (TimecardUtils.WORK_FLG_ON.equals(rd.getWorkFlag().getValue())) {
startDate = rd.getWorkDate().getValue();
if (kinmuStartDate.equals(startDate)
|| (kinmuStartDate.before(startDate) && kinmuEndDate
.after(startDate))) {
iszangyo = false;
} else {
iszangyo = true;
}
} else if (TimecardUtils.WORK_FLG_OFF.equals(rd
.getWorkFlag()
.getValue())) {
endDate = rd.getWorkDate().getValue();
long millisecond = endDate.getTime() - startDate.getTime();
shugyo_temp += millisecond / 1000 / 60;
if (iszangyo) {
zangyo_temp += millisecond / 1000 / 60;
} else {
jikannai_temp += millisecond / 1000 / 60;
}
}
}
// 集計した結果を各変数にセットする。
// 勤務時間内
this.jikannai1.setValue(jikannai_temp);
// if (settings != null && jikannai_temp >= settings.getWorktimeIn()) {
if (jikannai_temp >= settings.getWorktimeIn()) {
this.jikannai.setValue(jikannai_temp - settings.getResttimeIn());
this.jikannai2.setValue(settings.getResttimeIn());
} else {
this.jikannai.setValue(jikannai_temp);
this.jikannai2.setValue(0);
}
// 勤務時間外
long nnn = zangyo_temp / settings.getWorktimeOut().intValue();
this.zangyo.setValue(zangyo_temp - settings.getResttimeOut() * nnn);
this.zangyo1.setValue(zangyo_temp);
this.zangyo2.setValue(settings.getResttimeOut() * nnn);
// 勤務時間内・外
this.shugyo.setValue(this.jikannai.getValue() + this.zangyo.getValue());
// 遅刻
if (tempList.size() > 0) {
if (kinmuStartDate.before(tempList.get(0).getWorkDate().getValue())) {
this.chikoku.setValue("○");
}
}
// 相対
if (tempList.size() > 0) {
if (kinmuEndDate.after(tempList
.get(tempList.size() - 1)
.getWorkDate()
.getValue())) {
this.sotai.setValue("○");
}
}
} catch (RuntimeException ex) {
ex.printStackTrace();
throw ex;
}
}
/**
* TimecardResultDataオブジェクトのインスタンスを作る
*
* @param date
* @param workflag
* @return
*/
private TimecardResultData createTimecardResultData(Date date, String workflag) {
TimecardResultData rd = new TimecardResultData();
rd.initField();
rd.setWorkDate(date);
rd.setWorkFlag(workflag);
return rd;
}
/**
* 勤務時間設定をDBから取得する
*
* @return
*/
private EipTTimecardSettings loadEipTTimecardSettings() {
SelectQuery<EipTTimecardSettings> query =
Database.query(EipTTimecardSettings.class);
return query.fetchSingle();
}
}