package se.idega.idegaweb.commune.childcare.business; import java.io.InputStream; import java.sql.Timestamp; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.GregorianCalendar; import java.util.Iterator; import java.util.Vector; import se.idega.idegaweb.commune.care.data.ChildCareContract; import se.idega.idegaweb.commune.care.data.ChildCareContractHome; import com.idega.block.school.business.SchoolBusiness; import com.idega.block.school.data.SchoolClassMember; import com.idega.block.school.data.SchoolClassMemberHome; import com.idega.block.school.data.SchoolClassMemberLog; import com.idega.block.school.data.SchoolClassMemberLogHome; import com.idega.business.IBOLookup; import com.idega.business.IBOLookupException; import com.idega.core.file.data.ICFile; import com.idega.core.file.data.ICFileHome; import com.idega.data.IDOLookup; import com.idega.data.IDOLookupException; import com.idega.io.MemoryFileBuffer; import com.idega.io.MemoryInputStream; import com.idega.io.MemoryOutputStream; import com.idega.presentation.IWContext; import com.idega.util.IWTimestamp; public class ContractAndPlacementChangesExportWriter { public static final String SEPARATOR = ";"; IWContext iwc; private boolean isDebuggingGoingOn = false; public boolean createExportFile(IWContext iwc, ICFile folder) { this.iwc = iwc; try { MemoryFileBuffer buffer = new MemoryFileBuffer(); MemoryOutputStream mos = new MemoryOutputStream(buffer); Iterator iter = getExportData().iterator(); while (iter.hasNext()) { DataForExport row = (DataForExport) iter.next(); mos.write(row.getContents().getBytes("UTF8")); //XXX check for npe!! } buffer.setMimeType("text/plain"); InputStream mis = new MemoryInputStream(buffer); ICFileHome icFileHome = (ICFileHome) IDOLookup.getHome(ICFile.class); ICFile file = icFileHome.create(); file.setFileValue(mis); file.setMimeType("text/plain"); IWTimestamp toDate = new IWTimestamp(); String s = toDate.toString().replaceAll(":", ""); // on windows filenames cannot contain colons file.setName("export " + s + ".txt"); file.setFileSize(buffer.length()); file.store(); mos.close(); mis.close(); folder.addChild(file); return true; } catch(Exception e) { e.printStackTrace(); return false; } } private Date getFirstDateOfCurrentMonth() { Calendar cal = roundCalendarToDate(new GregorianCalendar()); if (isDebuggingGoingOn) { cal.add(Calendar.YEAR, -1); cal.add(Calendar.MONTH, -1); } int firstDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH); // It will be 1 cal.set(Calendar.DAY_OF_MONTH, firstDay); return new Date(cal.getTimeInMillis()); } private Date getLastDateOfCurrentMonth() { Calendar cal = roundCalendarToDate(new GregorianCalendar()); if (isDebuggingGoingOn) { cal.add(Calendar.YEAR, -1); } int days = cal.getActualMaximum(Calendar.DAY_OF_MONTH); cal.set(Calendar.DAY_OF_MONTH, days); return new Date(cal.getTimeInMillis()); } private Calendar roundCalendarToDate(Calendar cal){ cal.set(Calendar.HOUR, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); return cal; } private Date timestampToRoundedDate(Timestamp stamp) { if (stamp == null) return null; Calendar cal = new GregorianCalendar(); cal.setTimeInMillis(stamp.getTime()); return roundCalendarToDate(cal).getTime(); } /* private Date roundDateToDayOfMonth(Date date) { if (date == null) return null; Calendar cal = new GregorianCalendar(); cal.setTimeInMillis(date.getTime()); return roundCalendarToDate(cal).getTime(); } private String nullStringToEmpty(String s) { if(s == null) { return ""; } else { return s; } } */ private String dateToString(Date date) { if(date == null) return ""; IWTimestamp stamp = new IWTimestamp(date); return stamp.getDateString("yyyy-MM-dd"); } private Collection getExportData() { Date firstDateOfCurrentMonth = this.getFirstDateOfCurrentMonth(); Date lastDateOfCurrentMonth = this.getLastDateOfCurrentMonth(); Vector uberCollection = new Vector(); try { //get all placements //retrieve the placements we need and add them to the ubercolection Iterator placementsIterator = getSchoolClassMemberHome().findAllByCategory(getSchoolBusiness().getCategoryChildcare()).iterator(); boolean takeThisPlacement = false; for(; placementsIterator.hasNext();) { SchoolClassMember placement = (SchoolClassMember) placementsIterator.next(); Date registerDate = timestampToRoundedDate(placement.getRegisterDate()); //java.sql.Timestamp; and only contains date if (registerDate == null ) continue; Date removedDate = timestampToRoundedDate(placement.getRemovedDate()); //java.sql.Timestamp; contains date and time //XXX this should be done in SQL in the first place if (registerDate.compareTo(lastDateOfCurrentMonth) > 0) continue; if (removedDate != null && removedDate.compareTo(firstDateOfCurrentMonth) < 0) continue; Iterator placementLogs = getSchoolClassMemberLogHome().findAllBySchoolClassMember(placement).iterator(); while (placementLogs.hasNext()){ takeThisPlacement = false; SchoolClassMemberLog log = (SchoolClassMemberLog) placementLogs.next(); Date startDate = log.getStartDate(); //java.util.Date, contains date only Date endDate = log.getEndDate(); //java.util.Date, contains date only // 2. IF it�s a new placement where sch_class_member.register_date >= 1st of current month // AND sch_class_member.register_date <= last date of current month if (registerDate.equals(startDate) & isDateInInterval(registerDate, firstDateOfCurrentMonth, lastDateOfCurrentMonth)) //placement started takeThisPlacement = true; // 3. IF it�s a placement that ends (has removed_date set in sch_class_member) and // sch_class_member.removed date <= last date of current month // and sch_class_member.removed date >= first date of current month if (removedDate != null && (isDateInInterval(removedDate, firstDateOfCurrentMonth, lastDateOfCurrentMonth) & removedDate.equals(endDate))) //placement ended takeThisPlacement = true; // 4. IF a group has been changed (new entry in sch_class_member_log with // sch_class_member_log.start date >= 1st of current month // AND sch_class_member_log.start date <= last date of current month) if (takeThisPlacement || isDateInInterval(startDate, firstDateOfCurrentMonth, lastDateOfCurrentMonth)) // group was changed { uberCollection.add(new DataForExport(log.getSchoolClassMember(),startDate, endDate, "care_time_string")); } } } //get all contracts //retrieve the contracts we need //... and add them to the ubercollection Iterator contractsIterator = getChildCareContractHome().findChangedBetween( new java.sql.Date(firstDateOfCurrentMonth.getTime()), new java.sql.Date(lastDateOfCurrentMonth.getTime())).iterator(); //TODO: check, if this date conversion is okay. while (contractsIterator.hasNext()) { ChildCareContract contract = (ChildCareContract) contractsIterator.next(); // 5. IF a caretime has been changed (new entry in comm_childcare_archive with // comm_childcare_archive.start date >=1st of current month AND comm_childcare_archive.start date <= last date of current month) Date validFromDate = contract.getValidFromDate(); //java.util.Date , only date if (validFromDate == null) continue; if ( isDateInInterval(validFromDate, firstDateOfCurrentMonth, lastDateOfCurrentMonth)) { uberCollection.add(new DataForExport(contract.getSchoolClassMember(),validFromDate, null, contract.getCareTime())); } } //reshuffle the ubercollection so it is in correct order Collections.sort(uberCollection); return uberCollection; } catch (Exception e) { e.printStackTrace(); return new Vector(); } } private boolean isDateInInterval(Date date, Date startDate, Date endDate) { return date.compareTo(startDate) >= 0 || date.compareTo(endDate) <= 0; } private SchoolClassMemberHome getSchoolClassMemberHome() throws IDOLookupException { return (SchoolClassMemberHome) IDOLookup.getHome(SchoolClassMember.class); } private SchoolClassMemberLogHome getSchoolClassMemberLogHome() throws IDOLookupException { return (SchoolClassMemberLogHome) IDOLookup.getHome(SchoolClassMemberLog.class); } private SchoolBusiness getSchoolBusiness() throws IBOLookupException{ return (SchoolBusiness) IBOLookup.getServiceInstance(iwc, SchoolBusiness.class); } private ChildCareContractHome getChildCareContractHome() throws IDOLookupException { return (ChildCareContractHome) IDOLookup.getHome(ChildCareContract.class); } private class DataForExport implements Comparable { String contents; Date startDate; public DataForExport(SchoolClassMember member, Date startDate, Date endDate, String careTimeString) { this.startDate = startDate; try { this.contents = member.getSchoolClass().getSchool().getExtraProviderId() + SEPARATOR + member.getSchoolClass().getGroupStringId() + SEPARATOR + member.getStudent().getPersonalID() + SEPARATOR + dateToString(startDate) + SEPARATOR + dateToString(endDate) + SEPARATOR + careTimeString + SEPARATOR + member.getSchoolType().getTypeStringId() + "\r\n"; } catch (Exception e) { System.out.println("error in DataForExport"); this.contents = ""; //XXX e.printStackTrace(); } } public int compareTo(Object arg0) { // must return > 0 if argument is smaller try { Date date = ((DataForExport) arg0).getStartDate(); if (this.getStartDate().after(date)) { return 1; } else if (this.getStartDate().before(date)) { return -1; } else { return 0; } } catch (Exception e) { e.printStackTrace(); return 0; } } public Date getStartDate() { return startDate; } public void setStartDate(Date startDate) { this.startDate = startDate; } public String getContents() { return contents; } public void setContents(String contents) { this.contents = contents; } } }