IDEMPIERE-608 Zk InfoSchedule: Replace TimeLine with Calendar component.

This commit is contained in:
Heng Sin Low 2013-02-04 18:09:59 +08:00
parent ae6f9fb243
commit 01d80efbb5
11 changed files with 512 additions and 460 deletions

View File

@ -114,6 +114,25 @@ public class TimeUtil
cal.set(Calendar.MILLISECOND, 0);
return new Timestamp (cal.getTimeInMillis());
} // getNextDay
/**
* Get earliest time of next day
* @param day day
* @return next day with 00:00
*/
static public Timestamp getPreviousDay (Timestamp day)
{
if (day == null)
day = new Timestamp(System.currentTimeMillis());
GregorianCalendar cal = new GregorianCalendar(Language.getLoginLanguage().getLocale());
cal.setTimeInMillis(day.getTime());
cal.add(Calendar.DAY_OF_YEAR, -1); // previous
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return new Timestamp (cal.getTimeInMillis());
} // getNextDay
/**
* Get last date in month

View File

@ -1,145 +0,0 @@
package org.adempiere.webui;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.adempiere.util.ServerContext;
import org.adempiere.webui.component.ZkCssHelper;
import org.adempiere.webui.session.SessionContextListener;
import org.compiere.model.MAssignmentSlot;
import org.compiere.model.ScheduleUtil;
import org.compiere.util.Env;
import org.zkforge.timeline.util.TimelineUtil;
import org.zkoss.xel.fn.XmlFns;
import org.zkoss.xml.XMLs;
public class TimelineEventFeed extends HttpServlet {
/**
* generated serial version Id
*/
private static final long serialVersionUID = 5507229085571123451L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
Properties ctx = (Properties)req.getSession().getAttribute(SessionContextListener.SESSION_CTX);
if (ctx == null) {
return;
}
ServerContext.setCurrentInstance(ctx);
try {
doGet0(req, resp);
} finally {
ServerContext.dispose();
}
}
private void doGet0(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
int resourceId = 0;
String resourceIdParam = req.getParameter("S_Resource_ID");
if (resourceIdParam != null && resourceIdParam.trim().length() > 0) {
try {
resourceId = Integer.parseInt(resourceIdParam.trim());
} catch (Exception e) {
return;
}
} else {
return;
}
String uuid = req.getParameter("uuid");
if (uuid == null || uuid.trim().length() == 0) return;
//String timeLineId = req.getParameter("tlid");
Date date = null;
String dateParam = req.getParameter("date");
if (dateParam != null && dateParam.trim().length() > 0) {
try {
date = DateFormat.getInstance().parse(dateParam);
} catch (ParseException e) {
return;
}
} else {
return;
}
resp.setContentType("application/xml");
ScheduleUtil m_model = new ScheduleUtil (Env.getCtx());
// Calculate Start Day
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(date);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.DAY_OF_MONTH, 1);
Timestamp startDate = new Timestamp(cal.getTimeInMillis());
// Calculate End Date
cal.add(Calendar.MONTH, 1);
Timestamp endDate = new Timestamp (cal.getTimeInMillis());
MAssignmentSlot[] mas = m_model.getAssignmentSlots (resourceId, startDate, endDate, null, true, null);
if (mas == null || mas.length == 0) return;
StringBuilder xml = new StringBuilder();
xml.append("<data>").append("\r\n");
for (MAssignmentSlot slot : mas) {
xml.append("<event ").append("\r\n");
xml.append(XmlFns.attr("start", TimelineUtil.formatDateTime(new Date(slot.getStartTime().getTime()))));
if (slot.getEndTime() != null) {
xml.append("\r\n");
xml.append(XmlFns.attr("end", TimelineUtil.formatDateTime(new Date(slot.getEndTime().getTime()))));
xml.append("\r\n");
xml.append(XmlFns.attr("isDuration", "true"));
}
xml.append(XmlFns.attr("color", "#"+ZkCssHelper.createHexColorString(slot.getColor(true))));
xml.append("\r\n")
.append(XmlFns.attr("title", slot.getName()))
.append("\r\n")
.append(">");
if (slot.getDescription() != null && slot.getDescription().trim().length() > 0) {
xml.append("\r\n")
.append(XMLs.encodeText(slot.getDescription() + "<br/>"));
}
if (slot.getMAssignment() != null) {
//encode assignment id as coordinate x
String link = "<a href=\"javascript:void(0)\" onclick=\""
+ "_ad_closeBuble(jq(this));"
+ "var widget = zk.Widget.$('" + uuid+"');"
+ "var event = new zk.Event(widget, 'onClick', {x:"
+ slot.getMAssignment().getS_ResourceAssignment_ID() + ",y: 0}, {toServer: true});"
+ "zAu.send(event);"
+ "\">Edit</a>";
xml.append("\r\n").append(XMLs.encodeText(link));
}
xml.append("\r\n").append("</event>").append("\r\n");
}
xml.append("</data>").append("\r\n");
PrintWriter writer = resp.getWriter();
BufferedWriter buffer = new BufferedWriter(writer);
buffer.write(xml.toString());
buffer.flush();
}
}

View File

@ -46,6 +46,7 @@ import org.adempiere.webui.apps.form.WCreateFromFactory;
import org.adempiere.webui.apps.form.WCreateFromWindow;
import org.adempiere.webui.component.Button;
import org.adempiere.webui.component.Listbox;
import org.adempiere.webui.component.Mask;
import org.adempiere.webui.component.ProcessInfoDialog;
import org.adempiere.webui.component.Window;
import org.adempiere.webui.component.ZkCssHelper;
@ -810,7 +811,7 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
private FindWindow findWindow;
private Div maskDiv;
private Div mask;
/**
* @see ToolbarListener#onLock()
@ -2527,23 +2528,21 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements
isProcessMandatory);
} // actionButton
private Div getMaskDiv() {
if (maskDiv == null) {
maskDiv = new Div();
maskDiv.setStyle("position: absolute; width: 100%; height: 100%; border: none; margin: 0; background-color: #e4e4e4; " +
"padding: 0; z-index:999; opacity:0.6; top: 0px; left: 0px;");
private Div getMask() {
if (mask == null) {
mask = new Mask();
}
return maskDiv;
return mask;
}
public void hideBusyMask() {
if (maskDiv != null && maskDiv.getParent() != null) {
maskDiv.detach();
if (mask != null && mask.getParent() != null) {
mask.detach();
}
}
public void showBusyMask() {
getComponent().getParent().appendChild(getMaskDiv());
getComponent().getParent().appendChild(getMask());
}
private void executeButtonProcess(final IProcessButton wButton,

View File

@ -0,0 +1,37 @@
/******************************************************************************
* Copyright (C) 2013 Heng Sin Low *
* Copyright (C) 2013 Trek Global *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program is distributed in the hope *
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.adempiere.webui.component;
import org.zkoss.zul.Div;
/**
* @author hengsin
*
*/
public class Mask extends Div {
/**
* generated serial
*/
private static final long serialVersionUID = -9068605816183445421L;
/**
* default constructor
*/
public Mask() {
setStyle("position: absolute; width: 100%; height: 100%; border: none; margin: 0; background-color: #e4e4e4; " +
"padding: 0; z-index:999; opacity:0.6; top: 0px; left: 0px;");
}
}

View File

@ -15,6 +15,7 @@ package org.adempiere.webui.dashboard;
import org.adempiere.webui.apps.AEnv;
import org.adempiere.webui.component.ToolBarButton;
import org.adempiere.webui.component.Window;
import org.adempiere.webui.panel.InfoPanel;
import org.adempiere.webui.window.InfoSchedule;
import org.compiere.model.MRole;
@ -188,7 +189,9 @@ public class DPViews extends DashboardPanel implements EventListener<Event> {
}
else if (actionCommand.equals("InfoSchedule") && AEnv.canAccessInfo("SCHEDULE"))
{
new InfoSchedule(null, false);
InfoSchedule is = new InfoSchedule(null, false);
is.setAttribute(Window.MODE_KEY, Mode.EMBEDDED);
AEnv.showWindow(is);
}
else if (actionCommand.equals("InfoOrder") && AEnv.canAccessInfo("ORDER"))
{

View File

@ -159,8 +159,10 @@ public class WAssignmentEditor extends WEditor implements ContextMenuListener {
vad.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
MResourceAssignment ma = vad.getMResourceAssignment();
processNewValue(oldValue, ma);
if (!vad.isCancelled()) {
MResourceAssignment ma = vad.getMResourceAssignment();
processNewValue(oldValue, ma);
}
}
});
vad.setTitle(null);
@ -169,13 +171,14 @@ public class WAssignmentEditor extends WEditor implements ContextMenuListener {
// Start InfoSchedule directly
else
{
@SuppressWarnings("unused")
final InfoSchedule is = new InfoSchedule(ma, true, new Callback<MResourceAssignment>() {
@Override
public void onCallback(MResourceAssignment ma) {
processNewValue(oldValue, ma);
}
});
AEnv.showWindow(is);
is.focus();
}
}
}

View File

@ -96,7 +96,7 @@ public class DefaultInfoFactory implements IInfoFactory {
} else if (tableName.equals("C_CashLine")) {
info = new InfoCashLinePanel (WindowNo, value,
multiSelection, whereClause, lookup);
} else if (tableName.equals("S_ResourceAssigment")) {
} else if (tableName.equals("S_ResourceAssignment")) {
info = new InfoAssignmentWindow(WindowNo, tableName, keyColumn, value, multiSelection, whereClause, AD_InfoWindow_ID, lookup);
if (!info.loadedOK()) {
info = new InfoAssignmentPanel (WindowNo, value,

View File

@ -16,27 +16,39 @@
*****************************************************************************/
package org.adempiere.webui.panel;
import java.text.DateFormat;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.logging.Level;
import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.component.Panel;
import org.adempiere.webui.component.ToolBarButton;
import org.adempiere.webui.event.DialogEvents;
import org.adempiere.webui.component.Window;
import org.adempiere.webui.component.ZkCssHelper;
import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.window.InfoSchedule;
import org.adempiere.webui.window.WAssignmentDialog;
import org.compiere.model.MResourceAssignment;
import org.compiere.model.MAssignmentSlot;
import org.compiere.model.ScheduleUtil;
import org.compiere.util.CLogger;
import org.compiere.util.Env;
import org.zkforge.timeline.Bandinfo;
import org.zkforge.timeline.Timeline;
import org.zkforge.timeline.event.BandScrollEvent;
import org.compiere.util.Util;
import org.zkoss.calendar.Calendars;
import org.zkoss.calendar.event.CalendarsEvent;
import org.zkoss.calendar.impl.SimpleCalendarEvent;
import org.zkoss.calendar.impl.SimpleCalendarModel;
import org.zkoss.util.Locales;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.MouseEvent;
import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Button;
import org.zkoss.zul.Label;
import org.zkoss.zul.North;
import org.zkoss.zul.South;
/**
* Visual and Control Part of Schedule.
@ -48,13 +60,14 @@ import org.zkoss.zk.ui.event.MouseEvent;
* Zk Port
* @author Low Heng Sin
*/
public class WSchedule extends Panel implements EventListener<Event>
public class WSchedule extends Window implements EventListener<Event>
{
/**
*
*/
private static final long serialVersionUID = 7714179510197450419L;
@SuppressWarnings("unused")
private InfoSchedule infoSchedule;
/**
@ -79,19 +92,36 @@ public class WSchedule extends Panel implements EventListener<Event>
/** Logger */
private static CLogger log = CLogger.getCLogger(WSchedule.class);
Timeline timeLine;
private Bandinfo hourBand;
private Bandinfo dayBand;
private ToolBarButton button;
private Bandinfo mthBand;
@SuppressWarnings("unused")
private Date m_center;
private MResourceAssignment _assignmentDialogResult;
private Component calendarContainer;
private Calendars calendars;
private SimpleCalendarModel scm;
private Button btnCurrentDate;
private Label lblDate;
private int S_Resource_ID;
private Component divArrowLeft;
private Component divArrowRight;
private Component divTabDay;
private Component divTabWeek;
private Component divTabWeekdays;
private Component divTabMonth;
private Borderlayout borderlayout;
/**
* Static init
* <pre>
@ -104,57 +134,71 @@ public class WSchedule extends Panel implements EventListener<Event>
{
this.getChildren().clear();
timeLine = new Timeline();
timeLine.setHeight("400px");
timeLine.setWidth("100%");
timeLine.setId("resoureSchedule");
calendarContainer = Executions.createComponents("calendar.zul", this, null);
this.appendChild(timeLine);
borderlayout = (Borderlayout) calendarContainer.getFellow("main");
borderlayout.setStyle("position: absolute; width: 98%; margin: auto;");
borderlayout.setHeight("100%");
if (borderlayout.getSouth() != null) {
borderlayout.getSouth().detach();
}
Component tmp = calendarContainer.getFellow("btnSwitchTimeZone");
if (tmp != null)
tmp.detach();
tmp = calendarContainer.getFellow("btnRefresh");
if (tmp != null)
tmp.detach();
tmp = calendarContainer.getFellow("lbxRequestTypes");
if (tmp != null)
tmp.getParent().detach();
tmp = calendarContainer.getFellow("FDOW");
if (tmp != null)
tmp.detach();
initBandInfo();
calendars = (Calendars) calendarContainer.getFellow("cal");
TimeZone timezone = SessionManager.getAppDesktop().getClientInfo().timeZone;
calendars.addTimeZone(timezone.getID(), timezone);
calendars.addEventListener(CalendarsEvent.ON_EVENT_CREATE, this);
calendars.addEventListener(CalendarsEvent.ON_EVENT_EDIT, this);
calendars.addEventListener(CalendarsEvent.ON_EVENT_UPDATE, this);
this.appendChild(calendarContainer);
btnCurrentDate = (Button) calendarContainer.getFellow("btnCurrentDate");
btnCurrentDate.addEventListener(Events.ON_CLICK, this);
lblDate = (Label) calendarContainer.getFellow("lblDate");
lblDate.addEventListener(Events.ON_CREATE, this);
divArrowLeft = calendarContainer.getFellow("divArrowLeft");
divArrowLeft.addEventListener("onMoveDate", this);
divArrowRight = calendarContainer.getFellow("divArrowRight");
divArrowRight.addEventListener("onMoveDate", this);
divTabDay = calendarContainer.getFellow("divTabDay");
divTabDay.addEventListener("onUpdateView", this);
divTabWeek = calendarContainer.getFellow("divTabWeek");
divTabWeek.addEventListener("onUpdateView", this);
divTabWeekdays = calendarContainer.getFellow("divTabWeekdays");
divTabWeekdays.addEventListener("onUpdateView", this);
divTabMonth = calendarContainer.getFellow("divTabMonth");
divTabMonth.addEventListener("onUpdateView", this);
button = new ToolBarButton();
button.setLabel("Edit");
button.setStyle("visibility: hidden; height: 0px; width: 0px");
button.addEventListener(Events.ON_CLICK, this);
this.appendChild(button);
divTabClicked(7);
} // jbInit
private void initBandInfo() {
if (hourBand != null)
hourBand.detach();
hourBand = new Bandinfo();
timeLine.appendChild(hourBand);
hourBand.setIntervalUnit("hour");
hourBand.setWidth("40%");
hourBand.setIntervalPixels(40);
hourBand.setTimeZone(SessionManager.getAppDesktop().getClientInfo().timeZone);
hourBand.setId("WScheduleHourBand");
if (dayBand != null)
dayBand.detach();
dayBand = new Bandinfo();
timeLine.appendChild(dayBand);
dayBand.setIntervalUnit("day");
dayBand.setWidth("35%");
dayBand.setIntervalPixels(100);
dayBand.setSyncWith(hourBand.getId());
dayBand.setTimeZone(SessionManager.getAppDesktop().getClientInfo().timeZone);
// listening band scroll event
dayBand.addEventListener("onBandScroll", this);
dayBand.setId("WScheduleDayBand");
if (mthBand != null)
mthBand.detach();
mthBand = new Bandinfo();
timeLine.appendChild(mthBand);
mthBand.setIntervalUnit("month");
mthBand.setWidth("25%");
mthBand.setIntervalPixels(150);
mthBand.setSyncWith(dayBand.getId());
mthBand.setTimeZone(SessionManager.getAppDesktop().getClientInfo().timeZone);
}
/**
* Recreate View
* @param S_Resource_ID Resource
@ -162,56 +206,130 @@ public class WSchedule extends Panel implements EventListener<Event>
*/
public void recreate (int S_Resource_ID, Date date)
{
hourBand.setDate(date);
// Elaine 2008/12/12
dayBand.setDate(date);
mthBand.setDate(date);
// if (m_center == null || date.getTime() != m_center.getTime())
// hourBand.scrollToCenter(date);
//
String feedUrl = "timeline?S_Resource_ID=" + S_Resource_ID + "&date=" + DateFormat.getInstance().format(date)
+ "&uuid=" + button.getUuid() + "&tlid=" + timeLine.getUuid();
hourBand.setEventSourceUrl(feedUrl);
dayBand.setEventSourceUrl(feedUrl);
this.S_Resource_ID = S_Resource_ID;
calendars.setCurrentDate(date);
updateModel();
} // recreate
public void onAssignmentCallback() {
if (_assignmentDialogResult != null)
infoSchedule.mAssignmentCallback(_assignmentDialogResult);
_assignmentDialogResult = null;
private void updateModel() {
ScheduleUtil m_model = new ScheduleUtil (Env.getCtx());
// Calculate Start Day
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(calendars.getCurrentDate());
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.DAY_OF_MONTH, 1);
Timestamp startDate = new Timestamp(cal.getTimeInMillis());
// Calculate End Date
cal.add(Calendar.MONTH, 1);
Timestamp endDate = new Timestamp (cal.getTimeInMillis());
scm = new SimpleCalendarModel();
if (S_Resource_ID > 0) {
MAssignmentSlot[] list = m_model.getAssignmentSlots (S_Resource_ID, startDate, endDate, null, true, null);
for(MAssignmentSlot mas : list) {
SimpleCalendarEvent event = new SimpleCalendarEvent();
event.setBeginDate(mas.getStartTime());
event.setEndDate(mas.getEndTime());
event.setTitle(mas.getName());
event.setContent(mas.getDescription());
event.setHeaderColor('#'+ZkCssHelper.createHexColorString(mas.getColor(true)));
event.setContentColor('#'+ZkCssHelper.createHexColorString(mas.getColor(true)));
if (!mas.isAssignment() || mas.getMAssignment().isConfirmed())
event.setLocked(true);
scm.add(event);
}
}
calendars.setModel(scm);
}
public SimpleCalendarModel getModel() {
return scm;
}
public void onEvent(Event event) throws Exception {
if (event instanceof MouseEvent) {
MouseEvent me = (MouseEvent) event;
if (me.getX() > 0) {
MResourceAssignment assignment = new MResourceAssignment(Env.getCtx(), me.getX(), null);
final WAssignmentDialog assignmentDialog = new WAssignmentDialog(assignment, false, infoSchedule.isCreateNew());
assignmentDialog.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
if (!assignmentDialog.isCancelled()) {
_assignmentDialogResult = assignmentDialog.getMResourceAssignment();
Events.echoEvent("onAssignmentCallback", WSchedule.this, null);
}
}
});
assignmentDialog.setTitle(null);
LayoutUtils.openPopupWindow(this, assignmentDialog, "at_pointer");
Events.postEvent(new Event(Events.ON_CLICK, assignmentDialog.getDateFrom()));
String type = event.getName();
if (type.equals(Events.ON_CLICK)) {
if (event.getTarget() == btnCurrentDate) {
btnCurrentDateClicked();
}
} else if (event instanceof BandScrollEvent){
BandScrollEvent e = (BandScrollEvent) event;
@SuppressWarnings("unused")
Date end = e.getMax();
@SuppressWarnings("unused")
Date start = e.getMin();
Date mid = e.getCenter();
if (mid != null) {
m_center = mid;
infoSchedule.dateCallback(mid);
} else if (type.equals(Events.ON_CREATE)) {
if (event.getTarget() == lblDate)
updateDateLabel();
} else if (type.equals("onMoveDate")) {
if (event.getTarget() == divArrowLeft)
divArrowClicked(false);
else if (event.getTarget() == divArrowRight)
divArrowClicked(true);
} else if (type.equals("onUpdateView")) {
String text = String.valueOf(event.getData());
int days = "Day".equals(text) ? 1: "5 Days".equals(text) ? 5: "Week".equals(text) ? 7: 0;
divTabClicked(days);
} else {
Events.sendEvent(this, event);
}
}
private void btnCurrentDateClicked() {
calendars.setCurrentDate(Calendar.getInstance(calendars.getDefaultTimeZone()).getTime());
updateDateLabel();
}
private void updateDateLabel() {
Date b = calendars.getBeginDate();
Date e = calendars.getEndDate();
SimpleDateFormat sdfV = new SimpleDateFormat("yyyy/MMM/dd", Locales.getCurrent());
sdfV.setTimeZone(calendars.getDefaultTimeZone());
lblDate.setValue(sdfV.format(b) + " - " + sdfV.format(e));
}
private void divArrowClicked(boolean isNext) {
if (isNext)
calendars.nextPage();
else
calendars.previousPage();
updateDateLabel();
updateModel();
}
private void divTabClicked(int days) {
if (days > 0) {
calendars.setMold("default");
calendars.setDays(days);
} else {
calendars.setMold("month");
}
updateDateLabel();
}
public void addNorthPane(Component pane) {
if (borderlayout != null) {
if (borderlayout.getNorth() != null) {
borderlayout.getNorth().detach();
}
North north = new North();
north.appendChild(pane);
borderlayout.appendChild(north);
}
}
public void addSouthPane(Component pane, String height) {
if (borderlayout != null) {
if (borderlayout.getSouth() != null) {
borderlayout.getSouth().detach();
}
South south = new South();
south.appendChild(pane);
if (!Util.isEmpty(height)) {
south.setHeight(height);
}
borderlayout.appendChild(south);
}
}
} // WSchedule

View File

@ -21,27 +21,19 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.logging.Level;
import org.adempiere.util.Callback;
import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.apps.AEnv;
import org.adempiere.webui.component.Button;
import org.adempiere.webui.component.ConfirmPanel;
import org.adempiere.webui.component.DatetimeBox;
import org.adempiere.webui.component.Grid;
import org.adempiere.webui.component.GridFactory;
import org.adempiere.webui.component.Label;
import org.adempiere.webui.component.ListItem;
import org.adempiere.webui.component.Listbox;
import org.adempiere.webui.component.Row;
import org.adempiere.webui.component.Rows;
import org.adempiere.webui.component.Mask;
import org.adempiere.webui.component.Window;
import org.adempiere.webui.component.ZkCssHelper;
import org.adempiere.webui.event.DialogEvents;
import org.adempiere.webui.panel.StatusBarPanel;
import org.adempiere.webui.panel.WSchedule;
import org.compiere.model.MAssignmentSlot;
import org.compiere.model.MResourceAssignment;
@ -53,12 +45,16 @@ import org.compiere.util.Env;
import org.compiere.util.KeyNamePair;
import org.compiere.util.Msg;
import org.compiere.util.TimeUtil;
import org.zkoss.calendar.event.CalendarsEvent;
import org.zkoss.calendar.impl.SimpleCalendarEvent;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Div;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Hlayout;
import org.zkoss.zul.Space;
import org.zkoss.zul.Vbox;
@ -83,6 +79,7 @@ public class InfoSchedule extends Window implements EventListener<Event>
*/
private static final long serialVersionUID = -5948901371276429661L;
private Callback<MResourceAssignment> m_callback;
private Component m_parent;
/**
* Constructor
@ -94,29 +91,34 @@ public class InfoSchedule extends Window implements EventListener<Event>
this(mAssignment, createNew, (Callback<MResourceAssignment>)null);
}
public InfoSchedule (MResourceAssignment mAssignment, boolean createNew, Callback<MResourceAssignment> callback)
{
this(mAssignment, createNew, (Component)null, callback);
}
/**
* Constructor
* @param mAssignment optional assignment
* @param createNew if true, allows to create new assignments
* @param listener
*/
public InfoSchedule (MResourceAssignment mAssignment, boolean createNew, Callback<MResourceAssignment> callback)
public InfoSchedule (MResourceAssignment mAssignment, boolean createNew, Component parent, Callback<MResourceAssignment> callback)
{
super();
setTitle(Msg.getMsg(Env.getCtx(), "InfoSchedule"));
if (createNew)
{
setAttribute(Window.MODE_KEY, Window.MODE_POPUP);
this.setWidth("600px");
setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED);
this.setWidth("700px");
this.setHeight("600px");
this.setSizable(true);
}
else
{
setAttribute(Window.MODE_KEY, Window.MODE_EMBEDDED);
this.setWidth("100%");
this.setHeight("100%");
}
// this.setHeight("600px");
this.setClosable(true);
this.setBorder("normal");
this.setStyle("position: absolute");
@ -131,11 +133,16 @@ public class InfoSchedule extends Window implements EventListener<Event>
m_dateFrom = new Timestamp(System.currentTimeMillis());
m_createNew = createNew;
m_callback = callback;
m_parent = parent;
if (callback != null) {
this.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
m_callback.onCallback(getMResourceAssignment());
if (!m_cancel) {
m_callback.onCallback(getMResourceAssignment());
} else {
m_callback.onCallback(null);
}
}
});
}
@ -148,7 +155,7 @@ public class InfoSchedule extends Window implements EventListener<Event>
{
log.log(Level.SEVERE, "InfoSchedule", ex);
}
AEnv.showWindow(this);
// AEnv.showWindow(this);
displayCalendar();
} // InfoSchedule
@ -172,21 +179,18 @@ public class InfoSchedule extends Window implements EventListener<Event>
private static CLogger log = CLogger.getCLogger(InfoSchedule.class);
private Vbox mainLayout = new Vbox();
private Grid parameterPanel = GridFactory.newGridLayout();
private Hlayout parameterPanel = new Hlayout();
private Label labelResourceType = new Label();
private Listbox fieldResourceType = new Listbox();
private Label labelResource = new Label();
private Listbox fieldResource = new Listbox();
// Elaine 2008/12/12
private Button bPrevious = new Button();
private Label labelDate = new Label();
private DatetimeBox fieldDate = new DatetimeBox();
private Button bNext = new Button();
//
private WSchedule schedulePane = new WSchedule(this);
private StatusBarPanel statusBar = new StatusBarPanel();
private ConfirmPanel confirmPanel = null;
private Button btnNew;
private WAssignmentDialog vad;
private boolean m_cancel = false;
private Mask mask;
/**
* Static Layout
@ -200,54 +204,36 @@ public class InfoSchedule extends Window implements EventListener<Event>
labelResourceType.setValue(Msg.translate(Env.getCtx(), "S_ResourceType_ID"));
labelResource.setValue(Msg.translate(Env.getCtx(), "S_Resource_ID"));
labelDate.setValue(Msg.translate(Env.getCtx(), "Date"));
// Elaine 2008/12/12
bPrevious.setLabel("<");
bNext.setLabel(">");
//
mainLayout.appendChild(parameterPanel);
Rows rows = new Rows();
rows.setParent(parameterPanel);
Row row = new Row();
rows.appendChild(row);
row.appendChild(labelResourceType);
row.appendChild(fieldResourceType);
row = new Row();
rows.appendChild(row);
row.appendChild(labelResource);
row.appendChild(fieldResource);
// Elaine 2008/12/12
row = new Row();
rows.appendChild(row);
row.appendChild(labelDate);
Hbox hbox = new Hbox();
hbox.appendChild(bPrevious);
hbox.appendChild(fieldDate);
hbox.appendChild(bNext);
row.appendChild(hbox);
//
parameterPanel.setValign("middle");
parameterPanel.appendChild(labelResourceType);
parameterPanel.appendChild(fieldResourceType);
parameterPanel.appendChild(new Space());
parameterPanel.appendChild(labelResource);
parameterPanel.appendChild(fieldResource);
mainLayout.appendChild(schedulePane);
schedulePane.setWidth("100%");
schedulePane.setHeight("400px");
Div div = new Div();
schedulePane.addNorthPane(parameterPanel);
if (m_createNew)
{
Div div = new Div();
confirmPanel = new ConfirmPanel(true);
div.appendChild(confirmPanel);
div.appendChild(confirmPanel);
schedulePane.addSouthPane(div, "80px");
schedulePane.addEventListener(CalendarsEvent.ON_EVENT_CREATE, this);
schedulePane.addEventListener(CalendarsEvent.ON_EVENT_EDIT, this);
schedulePane.addEventListener(CalendarsEvent.ON_EVENT_UPDATE, this);
}
else
{
schedulePane.addEventListener(CalendarsEvent.ON_EVENT_EDIT, this);
schedulePane.addEventListener(CalendarsEvent.ON_EVENT_UPDATE, this);
}
div.appendChild(statusBar);
mainLayout.appendChild(div);
fieldResourceType.setMold("select");
fieldResource.setMold("select");
fieldResource.setMold("select");
} // jbInit
/**
@ -262,25 +248,9 @@ public class InfoSchedule extends Window implements EventListener<Event>
fieldResourceType.addEventListener(Events.ON_SELECT, this);
fieldResource.addEventListener(Events.ON_SELECT, this);
// Date - Elaine 2008/12/12
fieldDate.setValue(m_dateFrom);
fieldDate.getDatebox().addEventListener(Events.ON_BLUR, this);
fieldDate.getTimebox().addEventListener(Events.ON_BLUR, this);
// fieldDate.addEventListener(Events.ON_BLUR, this);
bPrevious.addEventListener(Events.ON_CLICK, this);
bNext.addEventListener(Events.ON_CLICK, this);
//
//
if (createNew) {
confirmPanel.addActionListener(Events.ON_CLICK, this);
btnNew = new Button();
btnNew.setName("btnNew");
btnNew.setId("New");
btnNew.setImage("/images/New24.png");
confirmPanel.addComponentsLeft(btnNew);
btnNew.addEventListener(Events.ON_CLICK, this);
}
} // dynInit
@ -415,10 +385,8 @@ public class InfoSchedule extends Window implements EventListener<Event>
int S_Resource_ID = pp.getKey();
m_mAssignment.setS_Resource_ID(S_Resource_ID);
// Elaine 2008/12/12
Date date = fieldDate.getValue();
Date date = m_dateFrom;
if (date == null) date = new Timestamp(System.currentTimeMillis());
// Date date = m_dateFrom;
//
// Set Info
@ -442,12 +410,19 @@ public class InfoSchedule extends Window implements EventListener<Event>
* Callback.
* Called from WSchedule after WAssignmentDialog finished
* @param assignment New/Changed Assignment
* @param b
*/
public void mAssignmentCallback (MResourceAssignment assignment)
public void mAssignmentCallback (MResourceAssignment assignment, boolean createNew, boolean cancelled)
{
m_mAssignment = assignment;
if (m_createNew)
dispose();
hideBusyMask();
if (!cancelled)
{
m_mAssignment = assignment;
if (createNew)
dispose();
else
displayCalendar();
}
else
displayCalendar();
} // mAssignmentCallback
@ -465,57 +440,26 @@ public class InfoSchedule extends Window implements EventListener<Event>
if (m_loading)
return;
if (event.getTarget().getId().equals("Ok"))
if (event.getTarget().getId().equals("Ok")) {
m_cancel = false;
dispose();
else if (event.getTarget().getId().equals("Cancel"))
} else if (event.getTarget().getId().equals("Cancel")) {
m_cancel = true;
dispose();
//
else if (event.getTarget() == fieldResourceType)
} else if (event.getTarget() == fieldResourceType)
{
fillResource();
displayCalendar();
}
// Elaine 2008/12/12
else if (event.getTarget()== fieldResource
|| event.getTarget() == fieldDate.getDatebox()
|| event.getTarget() == fieldDate.getTimebox())
displayCalendar();
//
else if (event.getTarget() == bPrevious)
adjustDate(-1);
else if (event.getTarget() == bNext)
adjustDate(+1);
//
else if (event.getTarget().getId().equals("New"))
doAdd();
else if (event instanceof CalendarsEvent)
doEdit((CalendarsEvent)event);
//
}
// Elaine 2008/12/12
/**
* Adjust Date
* @param diff difference
*/
private void adjustDate (int diff)
{
Date date = fieldDate.getValue();
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(date);
// if (timePane.getSelectedIndex() == 0)
cal.add(java.util.Calendar.DAY_OF_YEAR, diff);
// else if (timePane.getSelectedIndex() == 1)
// cal.add(java.util.Calendar.WEEK_OF_YEAR, diff);
// else
// cal.add(java.util.Calendar.MONTH, diff);
//
fieldDate.setValue(new Timestamp(cal.getTimeInMillis()));
displayCalendar ();
} // adjustDate
//
private void doAdd() {
private void doEdit(CalendarsEvent event) {
ListItem listItem = fieldResource.getSelectedItem();
if (listItem == null)
return;
@ -524,50 +468,35 @@ public class InfoSchedule extends Window implements EventListener<Event>
int S_Resource_ID = pp.getKey();
ScheduleUtil schedule = new ScheduleUtil (Env.getCtx());
Timestamp start = m_dateFrom;
java.sql.Date startDate = new java.sql.Date(start.getTime());
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(startDate.getTime());
start = new Timestamp(startDate.getTime());
start = new Timestamp(cal.getTimeInMillis());
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
start = new Timestamp(cal.getTimeInMillis());
cal.add(Calendar.DAY_OF_MONTH, 1);
Timestamp end = new Timestamp(cal.getTimeInMillis());
MAssignmentSlot[] mas = schedule.getAssignmentSlots(S_Resource_ID, start, end, null, true, null);
MAssignmentSlot[] mts = schedule.getDayTimeSlots ();
Timestamp start = new Timestamp(event.getBeginDate() != null ? event.getBeginDate().getTime() : event.getCalendarEvent().getBeginDate().getTime());
Timestamp end =new Timestamp(event.getEndDate() != null ? event.getEndDate().getTime() : event.getCalendarEvent().getEndDate().getTime());
double hours = (end.getTime() - start.getTime())/ 1000d / 60d / 60d;
MAssignmentSlot[] mas = schedule.getAssignmentSlots(S_Resource_ID, TimeUtil.getPreviousDay(start), TimeUtil.getNextDay(end), null, true, null);
MAssignmentSlot slot = null;
for (int i = 0; i < mts.length; i++) {
slot = mts[i];
for(int j = 0; j < mas.length; j++) {
if (mts[i].getStartTime().getTime() == mas[j].getStartTime().getTime()) {
slot = null;
for(int i = 0; i < mas.length; i++) {
if (mas[i].getStartTime().getTime() == start.getTime()) {
slot = mas[i];
break;
}
if (mas[i].getEndTime() != null) {
if (start.getTime() > mas[i].getStartTime().getTime()
&& start.getTime() < mas[i].getEndTime().getTime()) {
slot = mas[i];
break;
} else if (end.getTime() > mas[i].getStartTime().getTime()
&& end.getTime() < mas[i].getEndTime().getTime()) {
slot = mas[i];
break;
} else if (start.getTime() < mas[i].getStartTime().getTime()
&& end.getTime() >= mas[i].getEndTime().getTime()) {
slot = mas[i];
break;
}
if (mas[j].getEndTime() != null) {
if (mts[i].getStartTime().getTime() > mas[j].getStartTime().getTime()
&& mts[i].getStartTime().getTime() < mas[j].getEndTime().getTime()) {
slot = null;
break;
} else if (mts[i].getEndTime().getTime() > mas[j].getStartTime().getTime()
&& mts[i].getEndTime().getTime() < mas[j].getEndTime().getTime()) {
slot = null;
break;
} else if (mts[i].getStartTime().getTime() < mas[j].getStartTime().getTime()
&& mts[i].getEndTime().getTime() >= mas[j].getEndTime().getTime()) {
slot = null;
break;
}
}
}
if (slot != null)
break;
}
if (slot != null) {
if (slot == null) {
MResourceAssignment ma;
if (m_mAssignment == null)
ma = new MResourceAssignment(Env.getCtx(), 0, null);
@ -575,19 +504,88 @@ public class InfoSchedule extends Window implements EventListener<Event>
ma = m_mAssignment;
ma.setS_Resource_ID(S_Resource_ID);
ma.setAssignDateFrom(TimeUtil.getDayTime(start, slot.getStartTime()));
ma.setQty(new BigDecimal(1));
final WAssignmentDialog vad = new WAssignmentDialog (ma, false, m_createNew);
vad.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
mAssignmentCallback(vad.getMResourceAssignment());
ma.setAssignDateFrom(start);
ma.setQty(new BigDecimal(hours));
if (m_parent == null || m_callback == null) {
final boolean createNew = true;
if (vad != null && vad.getPage() != null)
vad.detach();
vad = new WAssignmentDialog (ma, false, createNew);
if (event.getBeginDate() != null && event.getEndDate() != null) {
SimpleCalendarEvent newEvent = new SimpleCalendarEvent();
newEvent.setBeginDate(event.getBeginDate());
newEvent.setEndDate(event.getEndDate());
if (event.getCalendarEvent() != null) {
newEvent.setContent(event.getCalendarEvent().getContent());
newEvent.setContentColor(event.getCalendarEvent().getContentColor());
newEvent.setHeaderColor(event.getCalendarEvent().getHeaderColor());
newEvent.setTitle(event.getCalendarEvent().getTitle());
schedulePane.getModel().remove(event.getCalendarEvent());
}
schedulePane.getModel().add(newEvent);
}
});
vad.setTitle(null);
LayoutUtils.openPopupWindow(btnNew, vad, "before_start");
vad.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
mAssignmentCallback(vad.getMResourceAssignment(), createNew, vad.isCancelled());
}
});
vad.setTitle(null);
ZkCssHelper.appendStyle(vad, "position: absolute");
showBusyMask();
this.appendChild(vad);
LayoutUtils.openOverlappedWindow(this, vad, "middle_center");
vad.focus();
} else {
m_cancel = false;
m_mAssignment = ma;
dispose();
}
} else {
FDialog.error(0, this, "No available time slot for the selected day.");
if (!slot.isAssignment())
FDialog.error(0, this, "No available time slot for the selected day.");
MResourceAssignment ma = slot.getMAssignment();
ma.setAssignDateFrom(start);
ma.setQty(new BigDecimal(hours));
if (m_parent == null || m_callback == null) {
if (event.getBeginDate() != null && event.getEndDate() != null) {
SimpleCalendarEvent newEvent = new SimpleCalendarEvent();
newEvent.setBeginDate(event.getBeginDate());
newEvent.setEndDate(event.getEndDate());
if (event.getCalendarEvent() != null) {
newEvent.setContent(event.getCalendarEvent().getContent());
newEvent.setContentColor(event.getCalendarEvent().getContentColor());
newEvent.setHeaderColor(event.getCalendarEvent().getHeaderColor());
newEvent.setTitle(event.getCalendarEvent().getTitle());
schedulePane.getModel().remove(event.getCalendarEvent());
}
schedulePane.getModel().add(newEvent);
}
final boolean createNew = false;
if (vad != null && vad.getPage() != null)
vad.detach();
vad = new WAssignmentDialog (ma, false, createNew);
vad.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
mAssignmentCallback(vad.getMResourceAssignment(), createNew, vad.isCancelled());
}
});
vad.setTitle(null);
ZkCssHelper.appendStyle(vad, "position: absolute");
showBusyMask();
this.appendChild(vad);
LayoutUtils.openOverlappedWindow(this, vad, "middle_center");
vad.focus();
} else {
m_cancel = false;
m_mAssignment = ma;
dispose();
}
}
}
@ -601,7 +599,6 @@ public class InfoSchedule extends Window implements EventListener<Event>
*/
public void dateCallback(Date date) {
m_dateFrom = new Timestamp(date.getTime());
fieldDate.setValue(m_dateFrom); // Elaine 2008/12/15
}
/* (non-Javadoc)
@ -614,8 +611,24 @@ public class InfoSchedule extends Window implements EventListener<Event>
displayCalendar();
}
}
private Div getMask() {
if (mask == null) {
mask = new Mask();
}
return mask;
}
protected void showBusyMask() {
appendChild(getMask());
}
protected void hideBusyMask() {
if (mask != null && mask.getParent() != null) {
mask.detach();
}
}
/**
SELECT o.DocumentNo, ol.Line, ol.Description
FROM C_OrderLine ol, C_Order o

View File

@ -30,6 +30,7 @@ import java.util.logging.Level;
import org.adempiere.util.Callback;
import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.apps.AEnv;
import org.adempiere.webui.component.Button;
import org.adempiere.webui.component.ConfirmPanel;
import org.adempiere.webui.component.Datebox;
@ -135,7 +136,7 @@ public class WAssignmentDialog extends Window implements EventListener<Event>
private Datebox fDateFrom = new Datebox();
private Timebox fTimeFrom = new Timebox();
private Label lQty = new Label(Msg.translate(Env.getCtx(), "Qty"));
private NumberBox fQty = new NumberBox(true);
private NumberBox fQty = new NumberBox(false);
private Label lUOM = new Label();
private Label lName = new Label(Msg.translate(Env.getCtx(), "Name"));
private Label lDescription = new Label(Msg.translate(Env.getCtx(), "Description"));
@ -143,7 +144,8 @@ public class WAssignmentDialog extends Window implements EventListener<Event>
private Textbox fDescription = new Textbox();
private ConfirmPanel confirmPanel = new ConfirmPanel(true, false, false, false, false, true /*, true*/);
private Button delete = confirmPanel.createButton("Delete");
private boolean m_cancel = false;
private boolean m_cancel = true;
private boolean m_zoom;
/**
* Static Init
@ -376,6 +378,7 @@ public class WAssignmentDialog extends Window implements EventListener<Event>
// Zoom - InfoResource
else if (e.getTarget().getId().equals("Zoom"))
{
m_zoom = true;
setVisible(false);
Events.echoEvent("onShowSchedule", this, null);
}
@ -402,6 +405,7 @@ public class WAssignmentDialog extends Window implements EventListener<Event>
// OK - Save
else if (e.getTarget().getId().equals("Ok"))
{
m_cancel = false;
if (cmd_save())
detach();
}
@ -409,22 +413,21 @@ public class WAssignmentDialog extends Window implements EventListener<Event>
public void onShowSchedule()
{
@SuppressWarnings("unused")
InfoSchedule is = new InfoSchedule (m_mAssignment, true, new Callback<MResourceAssignment>() {
InfoSchedule is = new InfoSchedule (m_mAssignment, true, this, new Callback<MResourceAssignment>() {
@Override
public void onCallback(MResourceAssignment result) {
m_zoom = false;
if (result != null)
{
m_mAssignment = result;
// setDisplay();
detach();
setDisplay();
}
else
{
setVisible(true);
}
setVisible(true);
WAssignmentDialog.this.focus();
}
});
AEnv.showWindow(is);
is.focus();
}
private void getDateAndTimeFrom(Calendar date) {
@ -444,4 +447,17 @@ public class WAssignmentDialog extends Window implements EventListener<Event>
public Datebox getDateFrom() {
return fDateFrom;
}
@Override
public boolean setVisible(boolean visible) {
boolean b = super.setVisible(visible);
if (!m_zoom && b && !visible) {
if (getModeType() == Mode.POPUP) {
this.detach();
}
}
return b;
}
} // VAssignmentDialog

View File

@ -106,17 +106,6 @@
<url-pattern>/zkau/*</url-pattern>
</servlet-mapping>
<!-- //// -->
<servlet>
<description>servlet to provide timeline xml event feed</description>
<servlet-name>timelineFeed</servlet-name>
<servlet-class>
org.adempiere.webui.TimelineEventFeed
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>timelineFeed</servlet-name>
<url-pattern>/timeline</url-pattern>
</servlet-mapping>
<!-- /////////// -->
<!-- Miscellaneous -->