📄 timesheetutils.java
字号:
package net.java.workeffort.service.support;import java.math.BigDecimal;import java.text.FieldPosition;import java.text.ParseException;import java.text.ParsePosition;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Calendar;import java.util.Collection;import java.util.Currency;import java.util.Date;import java.util.Iterator;import java.util.List;import java.util.Locale;import net.java.workeffort.infrastructure.LabelValueBean;import net.java.workeffort.infrastructure.uom.CurrencyMismatchException;import net.java.workeffort.infrastructure.uom.Money;import net.java.workeffort.infrastructure.utils.DateRangePredicate;import net.java.workeffort.infrastructure.utils.DateRangeValidationUtils;import net.java.workeffort.service.domain.PartyRate;import net.java.workeffort.service.domain.TimeEntry;import net.java.workeffort.service.domain.Timesheet;import org.apache.commons.beanutils.PropertyUtils;import org.apache.commons.collections.CollectionUtils;import org.apache.commons.collections.FastHashMap;import org.apache.commons.collections.Predicate;import org.apache.commons.lang.Validate;/** * Timesheet utility.Includes methods used by the batch job to calculate * amounts for timesheets. * <p> * <code>timesheetPeriod</code> is set using IOC. * </p> * @author Antony Joseph */public class TimesheetUtils { public static final String WEEKLY = "WEEKLY"; public static final String SEMI_MONTHLY = "SEMI-MONTHLY"; // The maximum days any timesheet can hold in system (16 because of // Semi-monthly). public static final int MAX_DAYS = 16; private static int CACHE_SIZE = 20; // Days of Month private final static int dom[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; private final static String FROM_DATE_LOV = "-FDL-"; private final static String DATES_FOR_TIMESHEET = "-DFT-"; private String timesheetPeriod; //FastHashMap for thread safety private FastHashMap cacheMap; /** * Constructor */ public TimesheetUtils() { cacheMap = new FastHashMap(); cacheMap.setFast(true); } /** * @return timesheetPeriod */ public String getTimesheetPeriod() { return timesheetPeriod; } /** * set the timesheet period. IOC * @param timesheetPeriod The timesheet period (WEEKLY, SEMI-MONTHLY) */ public void setTimesheetPeriod(String timesheetPeriod) { this.timesheetPeriod = timesheetPeriod; } /** * Get the list of values of timesheet start dates * @param dateFormat The date format * @param locale The locale * @return List of LabelValueBean */ public List getTimesheetFromDtLov(String dateFormat, Locale locale) { String defaultFromDt = convertDateToString( getDefaultTimesheetFromDate(), dateFormat); StringBuffer key = new StringBuffer(); key.append(defaultFromDt); key.append(FROM_DATE_LOV); key.append(locale.toString()); List lov = (List) cacheMap.get(key.toString()); if (lov == null) { lov = new ArrayList(); List list = createTimesheetFromDatesLov(); for (int i = 0; i < list.size(); i++) { lov.add(new LabelValueBean(null, list.get(i))); } cacheMap.put(key.toString(), lov); } return lov; } /** * get the dates for a timesheet. Note that the dates are cached * @param fromDt The date * @param dateFormat The date format * @param locale The users locale * @return The list of dates for the timesheet */ public List getDatesForTimesheet(Date fromDt, String dateFormat, Locale locale) { StringBuffer key = new StringBuffer(); String dateString = convertDateToString(fromDt, dateFormat); key.append(dateString); key.append(DATES_FOR_TIMESHEET); key.append(locale.toString()); List lov = (List) cacheMap.get(key.toString()); if (lov == null) { lov = createDatesForTimesheet(dateString, dateFormat, locale); cacheMap.put(key.toString(), lov); } return lov; } /** * Get the default timesheet start date. * @return default date */ public Date getDefaultTimesheetFromDate() { Calendar cal = Calendar.getInstance(); if (WEEKLY.equals(timesheetPeriod)) { int weekDay = cal.get(Calendar.DAY_OF_WEEK); // Start of current week. cal.add(Calendar.DAY_OF_YEAR, -1 * (weekDay - Calendar.MONDAY)); } else if (SEMI_MONTHLY.equals(timesheetPeriod)) { if (cal.get(Calendar.DAY_OF_MONTH) > 15) cal.set(Calendar.DAY_OF_MONTH, 16); else cal.set(Calendar.DAY_OF_MONTH, 1); } else throw new IllegalStateException("Invalid timesheetPeriod:" + timesheetPeriod); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); return cal.getTime(); } /** * Clear the cache. */ public void clearCache() { cacheMap.clear(); } /** * Get the timesheets end date * @param fromDt The date * @param noOfDays The number of days in timesheet * @return default date */ public Date getTimesheetThruDate(Date fromDt, int noOfDays) { Calendar cal = Calendar.getInstance(); cal.setTime(fromDt); cal.add(Calendar.DAY_OF_YEAR, noOfDays - 1); return cal.getTime(); } // creates timesheet start dates for the list of values // @return List of Dates private List createTimesheetFromDatesLov() { if (cacheMap.size() > CACHE_SIZE) clearCache(); List list = new ArrayList(); if (WEEKLY.equals(timesheetPeriod)) { Calendar cal = Calendar.getInstance(); int weekDay = cal.get(Calendar.DAY_OF_WEEK); // Start of current week. cal.add(Calendar.DAY_OF_YEAR, -1 * (weekDay - Calendar.MONDAY)); // the 1st date in list is 6 months prior. cal.add(Calendar.DAY_OF_YEAR, -1 * 26 * 7); // The lov shows weeks for a year starting 6 months prior // to 6 months in the future. for (int i = 0; i < 52; i++) { cal.add(Calendar.DAY_OF_YEAR, 7); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); list.add(cal.getTime()); } } else if (SEMI_MONTHLY.equals(timesheetPeriod)) { Calendar cal = Calendar.getInstance(); int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH); if (dayOfMonth > 15) cal.set(Calendar.DAY_OF_MONTH, 16); else cal.set(Calendar.DAY_OF_MONTH, 1); cal.add(Calendar.MONTH, -6); for (int i = 0; i < 24; i++) { if (cal.get(Calendar.DAY_OF_MONTH) == 1) { cal.set(Calendar.DAY_OF_MONTH, 16); } else { cal.set(Calendar.DAY_OF_MONTH, 1); cal.add(Calendar.MONTH, 1); } cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); list.add(cal.getTime()); } } return list; } // The list of dates for a timesheet. private List createDatesForTimesheet(String dateString, String dateFormat, Locale locale) { if (cacheMap.size() > CACHE_SIZE) clearCache(); SimpleDateFormat sdf = new SimpleDateFormat(dateFormat); Date startDate = null; try { startDate = sdf.parse(dateString); } catch (ParseException e) { throw new RuntimeException("date parse error", e); } Calendar cal = Calendar.getInstance(); cal.setTime(startDate); List dateHeaders = new ArrayList(); sdf = new SimpleDateFormat("dd/E", locale); int noOfDays = getNoOfDaysInTimesheet(cal); if (noOfDays < 0) throw new IllegalStateException( "failed to calculate noOfDays for timesheet"); for (int i = 0; i < noOfDays; i++) { StringBuffer buf = new StringBuffer(); String dayString = sdf.format(cal.getTime(), buf, new FieldPosition(0)).toString(); dateHeaders.add(dayString); cal.add(Calendar.DAY_OF_YEAR, 1); } return dateHeaders; } //package level access for testing. int getNoOfDaysInTimesheet(Calendar calFromDt) { int noOfDays = -99; // just an invalid value if (WEEKLY.equals(timesheetPeriod)) { noOfDays = 7; } else if (SEMI_MONTHLY.equals(timesheetPeriod)) { int dayOfMonth = calFromDt.get(Calendar.DAY_OF_MONTH); if (dayOfMonth == 1) noOfDays = 15; else if (dayOfMonth == 16) { int daysOfMonth = dom[calFromDt.get(Calendar.MONTH)]; // leap year check if ((calFromDt.get(Calendar.YEAR) % 4 == 0) && calFromDt.get(Calendar.MONTH) == 1) { ++daysOfMonth; } noOfDays = daysOfMonth - 15; } else throw new InvalidTimesheetPeriodException("invalid fromDt:" + calFromDt); } return noOfDays; } public void validateTimesheetPeriod(Timesheet timesheet) throws InvalidTimesheetPeriodException, InvalidTimesheetPeriodException { Date fromDt = timesheet.getFromDt(); Date thruDt = timesheet.getThruDt(); Validate.notNull(fromDt, "fromDt cannot be null in timesheet:" + timesheet); Validate.notNull(thruDt, "thruDt cannot be null in timesheet:" + timesheet); Calendar calFromDt = Calendar.getInstance(); calFromDt.setTime(fromDt); if (WEEKLY.equals(timesheetPeriod)) { if (Calendar.MONDAY != calFromDt.get(Calendar.DAY_OF_WEEK)) throw new InvalidTimesheetPeriodException( "fromDt invalid. Not a monday:" + fromDt + " for period=" + timesheetPeriod); } else if (SEMI_MONTHLY.equals(timesheetPeriod)) { int dayOfMonth = calFromDt.get(Calendar.DAY_OF_MONTH); if ((dayOfMonth != 1) && (dayOfMonth != 16)) throw new InvalidTimesheetPeriodException( "fromDt invalid. Not the 1st or 16th:" + fromDt + " for period=" + timesheetPeriod);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -