From aa37528819b36e1b3afd33b7b7199de5444f7064 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Fri, 25 Jul 2008 02:37:26 +0000 Subject: [PATCH] * Implemented resource assignment editor. --- .../src/org/adempiere/webui/LayoutUtils.java | 28 ++ .../adempiere/webui/TimelineEventFeed.java | 8 +- .../webui/component/ConfirmPanel.java | 9 +- .../org/adempiere/webui/component/Grid.java | 5 + .../adempiere/webui/component/Listbox.java | 16 +- .../webui/editor/WAssignmentEditor.java | 148 +++++++ .../webui/editor/WebEditorFactory.java | 4 + .../org/adempiere/webui/panel/ADTabpanel.java | 8 +- .../org/adempiere/webui/panel/WSchedule.java | 125 ++++-- .../adempiere/webui/part/AbstractUIPart.java | 17 + .../adempiere/webui/part/MultiTabPart.java | 11 +- .../src/org/adempiere/webui/part/UIPart.java | 17 + .../adempiere/webui/part/WindowContainer.java | 11 +- .../adempiere/webui/window/InfoSchedule.java | 143 +++--- .../webui/window/WAssignmentDialog.java | 412 ++++++++++++++++++ zkwebui/js/layout.js | 8 + 16 files changed, 856 insertions(+), 114 deletions(-) create mode 100644 zkwebui/WEB-INF/src/org/adempiere/webui/editor/WAssignmentEditor.java create mode 100644 zkwebui/WEB-INF/src/org/adempiere/webui/window/WAssignmentDialog.java diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/LayoutUtils.java b/zkwebui/WEB-INF/src/org/adempiere/webui/LayoutUtils.java index 40e413984e..8b4a2cbb3b 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/LayoutUtils.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/LayoutUtils.java @@ -1,10 +1,30 @@ +/****************************************************************************** + * Copyright (C) 2008 Low Heng Sin All Rights Reserved. * + * 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; +import org.adempiere.webui.component.Label; import org.zkoss.zk.au.out.AuScript; +import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.HtmlBasedComponent; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zkex.zul.Borderlayout; +import org.zkoss.zul.Div; +/** + * + * @author Low Heng Sin + * + */ public final class LayoutUtils { /** @@ -32,5 +52,13 @@ public final class LayoutUtils { sclass = ""; return cls == null || ((" " + sclass + " ").indexOf(" " + cls + " ") > -1); + } + + public static Component makeRightAlign(Label label) { + Div div = new Div(); + div.setStyle("text-align: right"); + div.appendChild(label); + + return div; } } diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/TimelineEventFeed.java b/zkwebui/WEB-INF/src/org/adempiere/webui/TimelineEventFeed.java index cced24b922..29c7cf4378 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/TimelineEventFeed.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/TimelineEventFeed.java @@ -53,6 +53,8 @@ public class TimelineEventFeed extends HttpServlet { 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) { @@ -103,12 +105,12 @@ public class TimelineEventFeed extends HttpServlet { .append(">"); if (slot.getDescription() != null && slot.getDescription().trim().length() > 0) { xml.append("\r\n") - .append(XMLs.encodeText(slot.getDescription())) - .append("
"); + .append(XMLs.encodeText(slot.getDescription() + "
")); } if (slot.getMAssignment() != null) { //encode assignment id as coordinate x - String link = "Edit"; diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/component/ConfirmPanel.java b/zkwebui/WEB-INF/src/org/adempiere/webui/component/ConfirmPanel.java index 3f40a4dca1..4dc75944c5 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/component/ConfirmPanel.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/component/ConfirmPanel.java @@ -17,8 +17,10 @@ package org.adempiere.webui.component; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zul.Hbox; @@ -34,6 +36,8 @@ public final class ConfirmPanel extends Hbox private static final long serialVersionUID = 1L; + private Map buttonMap = new HashMap(); + /** * Creates a button of the specified id * @@ -63,6 +67,9 @@ public final class ConfirmPanel extends Hbox button.setName("btn"+name); button.setId(name); button.setSrc("images/"+name+"24.gif"); + + buttonMap.put(name, button); + return button; } @@ -200,7 +207,7 @@ public final class ConfirmPanel extends Hbox */ public Button getButton(String id) { - return (Button)this.getFellowIfAny(id); + return buttonMap.get(id); } /** diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/component/Grid.java b/zkwebui/WEB-INF/src/org/adempiere/webui/component/Grid.java index 2092c19517..941c3a28f7 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/component/Grid.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/component/Grid.java @@ -26,4 +26,9 @@ package org.adempiere.webui.component; public class Grid extends org.zkoss.zul.Grid { private static final long serialVersionUID = 1L; + + public void makeNoStrip() { + setSclass("grid-no-striped"); + setOddRowSclass("even"); + } } diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/component/Listbox.java b/zkwebui/WEB-INF/src/org/adempiere/webui/component/Listbox.java index 606973a2fc..03ded3f6dc 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/component/Listbox.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/component/Listbox.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; +import org.compiere.util.KeyNamePair; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; @@ -42,8 +43,21 @@ public class Listbox extends org.zkoss.zul.Listbox implements EventListener private List doubleClickListeners = new ArrayList(); private List onDropListeners = new ArrayList(); private boolean draggable; + + public Listbox() { + super(); + } - public void setEnabled(boolean enabled) + public Listbox(KeyNamePair[] pairs) { + super(); + if (pairs != null && pairs.length > 0) { + for(KeyNamePair pair : pairs) { + this.appendItem(pair.getName(), pair.getKey()); + } + } + } + + public void setEnabled(boolean enabled) { this.setDisabled(!enabled); } diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/editor/WAssignmentEditor.java b/zkwebui/WEB-INF/src/org/adempiere/webui/editor/WAssignmentEditor.java new file mode 100644 index 0000000000..bc2ed9fa95 --- /dev/null +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/editor/WAssignmentEditor.java @@ -0,0 +1,148 @@ +package org.adempiere.webui.editor; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.text.DateFormat; +import java.text.NumberFormat; +import java.util.logging.Level; + +import org.adempiere.webui.component.EditorBox; +import org.adempiere.webui.event.ValueChangeEvent; +import org.adempiere.webui.window.InfoSchedule; +import org.adempiere.webui.window.WAssignmentDialog; +import org.compiere.model.GridField; +import org.compiere.model.MResourceAssignment; +import org.compiere.util.CLogger; +import org.compiere.util.DB; +import org.compiere.util.DisplayType; +import org.compiere.util.Env; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.Events; + +public class WAssignmentEditor extends WEditor { + + private final static CLogger log = CLogger.getCLogger(WAssignmentEditor.class); + + private boolean m_readWrite; + private Object m_value; + private PreparedStatement m_pstmt; + + private DateFormat m_dateFormat = DisplayType.getDateFormat(DisplayType.DateTime); + private NumberFormat m_qtyFormat = DisplayType.getNumberFormat(DisplayType.Quantity); + + public WAssignmentEditor(GridField gridField) { + super(new EditorBox(), gridField); + + initComponents(); + } + + private void initComponents() { + getComponent().getTextBox().setReadonly(true); + getComponent().setButtonImage("images/Assignment10.gif"); + getComponent().addEventListener(Events.ON_CLICK, this); + } + + + @Override + public EditorBox getComponent() { + return (EditorBox) component; + } + + @Override + public String getDisplay() { + return getComponent().getText(); + } + + @Override + public Object getValue() { + return m_value; + } + + @Override + public boolean isReadWrite() { + return m_readWrite; + } + + @Override + public void setReadWrite(boolean readWrite) { + m_readWrite = readWrite; + getComponent().setEnabled(readWrite); + getComponent().getTextBox().setReadonly(true); + } + + @Override + public void setValue(Object value) { + if (value == m_value) + return; + m_value = value; + int S_ResourceAssignment_ID = 0; + if (m_value != null && m_value instanceof Integer) + S_ResourceAssignment_ID = ((Integer)m_value).intValue(); + // Set Empty + if (S_ResourceAssignment_ID == 0) + { + getComponent().setText(""); + return; + } + + // Statement + if (m_pstmt == null) + m_pstmt = DB.prepareStatement("SELECT r.Name,ra.AssignDateFrom,ra.Qty,uom.UOMSymbol " + + "FROM S_ResourceAssignment ra, S_Resource r, S_ResourceType rt, C_UOM uom " + + "WHERE ra.S_ResourceAssignment_ID=?" + + " AND ra.S_Resource_ID=r.S_Resource_ID" + + " AND r.S_ResourceType_ID=rt.S_ResourceType_ID" + + " and rt.C_UOM_ID=uom.C_UOM_ID", null); + // + try + { + m_pstmt.setInt(1, S_ResourceAssignment_ID); + ResultSet rs = m_pstmt.executeQuery(); + if (rs.next()) + { + StringBuffer sb = new StringBuffer(rs.getString(1)); + sb.append(" ").append(m_dateFormat.format(rs.getTimestamp(2))) + .append(" ").append(m_qtyFormat.format(rs.getBigDecimal(3))) + .append(" ").append(rs.getString(4).trim()); + getComponent().setText(sb.toString()); + } + else + getComponent().setText("<" + S_ResourceAssignment_ID + ">"); + rs.close(); + } + catch (Exception e) + { + log.log(Level.SEVERE, "", e); + } + + } + + public void onEvent(Event event) throws Exception { + // + Integer oldValue = (Integer)getValue(); + int S_ResourceAssignment_ID = oldValue == null ? 0 : oldValue.intValue(); + MResourceAssignment ma = new MResourceAssignment(Env.getCtx(), S_ResourceAssignment_ID, null); + + // Start VAssignment Dialog + if (S_ResourceAssignment_ID != 0) + { + WAssignmentDialog vad = new WAssignmentDialog (ma, true, true); + ma = vad.getMResourceAssignment(); + } + // Start InfoSchedule directly + else + { + InfoSchedule is = new InfoSchedule(ma, true); + ma = is.getMResourceAssignment(); + } + + // Set Value + if (ma != null && ma.getS_ResourceAssignment_ID() != 0) + { + setValue(new Integer(ma.getS_ResourceAssignment_ID())); + ValueChangeEvent vce = new ValueChangeEvent(this, gridField.getColumnName(), oldValue, getValue()); + fireValueChange(vce); + } + } + +} diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/editor/WebEditorFactory.java b/zkwebui/WEB-INF/src/org/adempiere/webui/editor/WebEditorFactory.java index e51546a043..4362a3762c 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/editor/WebEditorFactory.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/editor/WebEditorFactory.java @@ -162,6 +162,10 @@ public class WebEditorFactory { editor = new WPAttributeEditor(gridTab, gridField); } + else if (displayType == DisplayType.Assignment) + { + editor = new WAssignmentEditor(gridField); + } else { editor = new WUnknownEditor(gridField); diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/ADTabpanel.java b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/ADTabpanel.java index 1191d5a453..2a67884ab8 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/ADTabpanel.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/ADTabpanel.java @@ -151,12 +151,10 @@ DataStatusListener, ValueChangeListener, IADTabpanel grid = new Grid(); //have problem moving the following out as css class grid.setWidth("99%"); - grid.setHeight("100%"); - grid.setSclass("grid-no-striped"); + grid.setHeight("100%"); grid.setStyle("margin:0; padding:0; position: absolute"); - grid.setOddRowSclass("even"); - - + grid.makeNoStrip(); + listPanel = new GridPanel(); listPanel.getListbox().addEventListener(Events.ON_DOUBLE_CLICK, this); diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/WSchedule.java b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/WSchedule.java index 9116067446..6acecee30d 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/WSchedule.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/WSchedule.java @@ -23,12 +23,16 @@ import java.util.logging.*; import org.adempiere.webui.component.Panel; import org.adempiere.webui.component.ToolBarButton; import org.adempiere.webui.window.InfoSchedule; +import org.adempiere.webui.window.WAssignmentDialog; +import org.compiere.model.MResourceAssignment; import org.compiere.util.*; import org.zkforge.timeline.Bandinfo; import org.zkforge.timeline.Timeline; +import org.zkforge.timeline.event.BandScrollEvent; 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; /** * Visual and Control Part of Schedule. @@ -36,6 +40,9 @@ import org.zkoss.zk.ui.event.Events; * * @author Jorg Janke * @version $Id: VSchedule.java,v 1.3 2006/07/30 00:51:27 jjanke Exp $ + * + * Zk Port + * @author Low Heng Sin */ public class WSchedule extends Panel implements EventListener { @@ -49,6 +56,7 @@ public class WSchedule extends Panel implements EventListener public WSchedule (InfoSchedule is) { infoSchedule = is; + try { init(); @@ -56,18 +64,24 @@ public class WSchedule extends Panel implements EventListener catch(Exception e) { log.log(Level.SEVERE, "VSchedule", e); - } + } } // WSchedule /** Logger */ private static CLogger log = CLogger.getCLogger(WSchedule.class); - Timeline schedulePanel; + Timeline timeLine; private Bandinfo hourBand; private Bandinfo dayBand; private ToolBarButton button; + private Bandinfo mthBand; + + private Date m_center; + + private MResourceAssignment _assignmentDialogResult; + /** * Static init *
@@ -78,30 +92,16 @@ public class WSchedule extends Panel implements EventListener
 	 */
 	private void init() throws Exception
 	{
-		schedulePanel = new Timeline();
-		schedulePanel.setHeight("400px");
-		schedulePanel.setWidth("100%");
-		schedulePanel.setId("resoureSchedule");
+		this.getChildren().clear();
+				
+		timeLine = new Timeline();
+		timeLine.setHeight("400px");
+		timeLine.setWidth("100%");
+		timeLine.setId("resoureSchedule");
 		
-		this.appendChild(schedulePanel);
+		this.appendChild(timeLine);		
 		
-		hourBand = new Bandinfo();
-		schedulePanel.appendChild(hourBand);
-		hourBand.setIntervalUnit("hour");
-		hourBand.setWidth("60%");
-		hourBand.setIntervalPixels(40);
-		hourBand.setId("hour");
-		hourBand.setTimeZone(TimeZone.getDefault());
-		
-		dayBand = new Bandinfo();
-		schedulePanel.appendChild(dayBand);
-		dayBand.setIntervalUnit("day");
-		dayBand.setWidth("40%");
-		dayBand.setIntervalPixels(100);
-		dayBand.setId("day");
-		dayBand.setSyncWith("hour");		
-		dayBand.setTimeZone(TimeZone.getDefault());
-		dayBand.setShowEventText(false);
+		initBandInfo();
 		
 		button = new ToolBarButton();
 		button.setLabel("Edit");
@@ -110,6 +110,41 @@ public class WSchedule extends Panel implements EventListener
 		this.appendChild(button);
 	}	//	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(TimeZone.getDefault());
+		
+		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(TimeZone.getDefault());
+		dayBand.setShowEventText(false);
+		// listening band scroll event
+		dayBand.addEventListener("onBandScroll", this);
+		
+		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(TimeZone.getDefault());
+		mthBand.setShowEventText(false);		
+	}
+
 	/**
 	 * 	Recreate View
 	 * 	@param S_Resource_ID Resource
@@ -118,26 +153,42 @@ public class WSchedule extends Panel implements EventListener
 	public void recreate (int S_Resource_ID, Date date)
 	{
 		hourBand.setDate(date);
-		hourBand.scrollToCenter(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();
+			+ "&uuid=" + button.getUuid() + "&tlid=" + timeLine.getUuid();
 		hourBand.setEventSourceUrl(feedUrl);
 		dayBand.setEventSourceUrl(feedUrl);
-		schedulePanel.invalidate();
 	}	//	recreate
 
-	/**
-	 * 	Enable/disable to Create New Assignments
-	 * 	@param createNew if true, allows to create new Assignments
-	 */
-	public void setCreateNew (boolean createNew)
-	{
-//		schedulePanel.setCreateNew(createNew);
-	}	//	setCreateNew
-
+	public void onAssignmentCallback() {
+		if (_assignmentDialogResult != null)
+			infoSchedule.mAssignmentCallback(_assignmentDialogResult);
+		_assignmentDialogResult = null;
+	}
+	
 	public void onEvent(Event event) throws Exception {
-		//TODO: Edit, S_ResourceAssignment_ID is in MouseEvent.x
+		if (event instanceof MouseEvent) {
+			MouseEvent me = (MouseEvent) event;
+			if (me.getX() > 0) {
+				MResourceAssignment assignment = new MResourceAssignment(Env.getCtx(), me.getX(), null);
+				WAssignmentDialog wad = new WAssignmentDialog(assignment, false, infoSchedule.isCreateNew());
+				if (!wad.isCancelled()) {
+					_assignmentDialogResult =  wad.getMResourceAssignment();
+					Events.echoEvent("onAssignmentCallback", this, null);				
+				}
+			}
+		} else if (event instanceof BandScrollEvent){
+			BandScrollEvent e = (BandScrollEvent) event;
+			Date end = e.getMax();
+			Date start = e.getMin();
+			Date mid = e.getCenter();
+			if (mid != null) {
+				m_center = mid;
+				infoSchedule.dateCallback(mid);
+			}
+		}
 	}
 
 }	//	WSchedule
diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/part/AbstractUIPart.java b/zkwebui/WEB-INF/src/org/adempiere/webui/part/AbstractUIPart.java
index 71c6a66576..7a63e03d63 100644
--- a/zkwebui/WEB-INF/src/org/adempiere/webui/part/AbstractUIPart.java
+++ b/zkwebui/WEB-INF/src/org/adempiere/webui/part/AbstractUIPart.java
@@ -1,8 +1,25 @@
+/******************************************************************************
+ * Copyright (C) 2008 Low Heng Sin  All Rights Reserved.                      *
+ * 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.part;
 
 import org.zkoss.zk.ui.Component;
 import org.zkoss.zk.ui.Page;
 
+/**
+ * 
+ * @author Low Heng Sin
+ *
+ */
 public abstract class AbstractUIPart implements UIPart {
 	
 	protected Page page = null;
diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/part/MultiTabPart.java b/zkwebui/WEB-INF/src/org/adempiere/webui/part/MultiTabPart.java
index f63896fb2f..2bc6d58e3c 100644
--- a/zkwebui/WEB-INF/src/org/adempiere/webui/part/MultiTabPart.java
+++ b/zkwebui/WEB-INF/src/org/adempiere/webui/part/MultiTabPart.java
@@ -1,6 +1,5 @@
 /******************************************************************************
- * Product: Posterita Ajax UI 												  *
- * Copyright (C) 2007 Posterita Ltd.  All Rights Reserved.                    *
+ * Copyright (C) 2008 Low Heng Sin  All Rights Reserved.                      *
  * 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   *
@@ -10,9 +9,6 @@
  * 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.                     *
- * For the text or an alternative of this public license, you may reach us    *
- * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius                 *
- * or via info@posterita.org or http://www.posterita.org/                     *
  *****************************************************************************/
 
 package org.adempiere.webui.part;
@@ -25,10 +21,9 @@ import org.adempiere.webui.component.Tabs;
 import org.zkoss.zk.ui.Component;
 
 /**
+ * 
+ * @author Low Heng Sin
  *
- * @author Ashley G Ramdass
- * @date Mar 3, 2007
- * @version $Revision: 0.10 $
  */
 public class MultiTabPart extends AbstractUIPart
 {
diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/part/UIPart.java b/zkwebui/WEB-INF/src/org/adempiere/webui/part/UIPart.java
index c028b9ae0c..f8ce67782e 100644
--- a/zkwebui/WEB-INF/src/org/adempiere/webui/part/UIPart.java
+++ b/zkwebui/WEB-INF/src/org/adempiere/webui/part/UIPart.java
@@ -1,7 +1,24 @@
+/******************************************************************************
+ * Copyright (C) 2008 Low Heng Sin  All Rights Reserved.                      *
+ * 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.part;
 
 import org.zkoss.zk.ui.Component;
 
+/**
+ * 
+ * @author Low Heng Sin
+ *
+ */
 public interface UIPart {
 	
 	public Component createPart(Object parent);
diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/part/WindowContainer.java b/zkwebui/WEB-INF/src/org/adempiere/webui/part/WindowContainer.java
index ede690129e..437e487886 100644
--- a/zkwebui/WEB-INF/src/org/adempiere/webui/part/WindowContainer.java
+++ b/zkwebui/WEB-INF/src/org/adempiere/webui/part/WindowContainer.java
@@ -1,6 +1,5 @@
 /******************************************************************************
- * Product: Posterita Ajax UI 												  *
- * Copyright (C) 2007 Posterita Ltd.  All Rights Reserved.                    *
+ * Copyright (C) 2008 Low Heng Sin  All Rights Reserved.                      *
  * 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   *
@@ -10,9 +9,6 @@
  * 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.                     *
- * For the text or an alternative of this public license, you may reach us    *
- * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius                 *
- * or via info@posterita.org or http://www.posterita.org/                     *
  *****************************************************************************/
 
 package org.adempiere.webui.part;
@@ -30,10 +26,9 @@ import org.zkoss.zk.ui.event.Events;
 import org.zkoss.zkex.zul.Borderlayout;
 
 /**
+ * 
+ * @author Low Heng Sin
  *
- * @author Ashley G Ramdass
- * @date Mar 3, 2007
- * @version $Revision: 0.10 $
  */
 public class WindowContainer extends AbstractUIPart implements EventListener
 {
diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/window/InfoSchedule.java b/zkwebui/WEB-INF/src/org/adempiere/webui/window/InfoSchedule.java
index a216374de3..f01790d464 100644
--- a/zkwebui/WEB-INF/src/org/adempiere/webui/window/InfoSchedule.java
+++ b/zkwebui/WEB-INF/src/org/adempiere/webui/window/InfoSchedule.java
@@ -16,6 +16,7 @@
  *****************************************************************************/
 package org.adempiere.webui.window;
 
+import java.math.BigDecimal;
 import java.sql.*;
 import java.util.*;
 import java.util.Date;
@@ -24,7 +25,6 @@ import java.util.logging.*;
 import org.adempiere.webui.apps.AEnv;
 import org.adempiere.webui.component.Button;
 import org.adempiere.webui.component.ConfirmPanel;
-import org.adempiere.webui.component.Datebox;
 import org.adempiere.webui.component.Grid;
 import org.adempiere.webui.component.Label;
 import org.adempiere.webui.component.ListItem;
@@ -63,8 +63,10 @@ public class InfoSchedule extends Window implements EventListener //, ChangeList
 	{
 		super();
 		setTitle(Msg.getMsg(Env.getCtx(), "InfoSchedule"));
-//		setAttribute("modal", Boolean.valueOf(createNew));
-		setAttribute("mode", "overlapped");
+		if (createNew)
+			setAttribute("mode", "modal");
+		else
+			setAttribute("mode", "overlapped");
 		this.setWidth("600px");
 		this.setHeight("600px");
 		this.setBorder("normal");
@@ -116,10 +118,7 @@ public class InfoSchedule extends Window implements EventListener //, ChangeList
 	private Listbox fieldResourceType = new Listbox();
 	private Label labelResource = new Label();
 	private Listbox fieldResource = new Listbox();
-	private Button bPrevious = new Button();
 	private Label labelDate = new Label();
-	private Datebox fieldDate = new Datebox();
-	private Button bNext = new Button();
 	private WSchedule schedulePane = new WSchedule(this);
 	private StatusBarPanel statusBar = new StatusBarPanel();
 	private ConfirmPanel confirmPanel = new ConfirmPanel(true);
@@ -136,9 +135,7 @@ public class InfoSchedule extends Window implements EventListener //, ChangeList
 		
 		labelResourceType.setValue(Msg.translate(Env.getCtx(), "S_ResourceType_ID"));
 		labelResource.setValue(Msg.translate(Env.getCtx(), "S_Resource_ID"));
-		bPrevious.setLabel("<");
 		labelDate.setValue(Msg.translate(Env.getCtx(), "Date"));
-		bNext.setLabel(">");
 		
 		mainLayout.appendChild(parameterPanel);
 		
@@ -148,17 +145,12 @@ public class InfoSchedule extends Window implements EventListener //, ChangeList
 		rows.appendChild(row);
 		
 		row.appendChild(labelResourceType);
-		row.appendChild(labelResource);
-		row.appendChild(bPrevious);
-		row.appendChild(labelDate);
-		row.appendChild(bNext);
+		row.appendChild(fieldResourceType);				
 		
 		row = new Row();
 		rows.appendChild(row);
-		row.appendChild(fieldResourceType);
+		row.appendChild(labelResource);
 		row.appendChild(fieldResource);
-		row.appendChild(new Label(" "));
-		row.appendChild(fieldDate);		
 		//
 		
 		mainLayout.appendChild(schedulePane);
@@ -186,19 +178,17 @@ public class InfoSchedule extends Window implements EventListener //, ChangeList
 		fieldResourceType.addEventListener(Events.ON_SELECT, this);
 		fieldResource.addEventListener(Events.ON_SELECT, this);
 
-		//	Date
-		fieldDate.setValue(m_dateFrom);
-		fieldDate.addEventListener(Events.ON_CHANGE, this);
-		bPrevious.addEventListener(Events.ON_CLICK, this);
-		bNext.addEventListener(Events.ON_CLICK, this);
-
 		//
 		confirmPanel.addActionListener(Events.ON_CLICK, this);
-		Button button = confirmPanel.createButton("Add");
-		confirmPanel.addComponentsLeft(button);
-		button.addEventListener(Events.ON_CLICK, this);
-		button.setLabel("Add");
-		
+		if (createNew) {
+			Button btnNew = new Button();
+	        btnNew.setName("btnNew");
+	        btnNew.setId("New");
+	        btnNew.setSrc("/images/New24.gif");
+	        
+			confirmPanel.addComponentsLeft(btnNew);			
+			btnNew.addEventListener(Events.ON_CLICK, this);
+		}
 		displayCalendar();
 	}	//	dynInit
 
@@ -332,7 +322,8 @@ public class InfoSchedule extends Window implements EventListener //, ChangeList
 		KeyNamePair pp = new KeyNamePair((Integer)listItem.getValue(), listItem.getLabel());
 		int S_Resource_ID = pp.getKey();
 		m_mAssignment.setS_Resource_ID(S_Resource_ID);
-		Date date = fieldDate.getValue();
+//		Date date = fieldDate.getValue();
+		Date date = m_dateFrom;
 
 		//	Set Info
 		m_loading = true;
@@ -349,25 +340,11 @@ public class InfoSchedule extends Window implements EventListener //, ChangeList
 		this.detach();
 	}	//	dispose
 
-	/**
-	 * 	Adjust Date
-	 * 	@param diff difference
-	 */
-	private void adjustDate (int diff)
-	{
-		Date date = fieldDate.getValue();
-		GregorianCalendar cal = new GregorianCalendar();
-		cal.setTime(date);
-		cal.add(java.util.Calendar.DAY_OF_YEAR, diff);
-		fieldDate.setValue(new Date(cal.getTimeInMillis()));
-		displayCalendar ();
-	}	//	adjustDate
-
 	/*************************************************************************/
 
 	/**
 	 * 	Callback.
-	 * 	Called from VSchedulePanel after VAssignmentDialog finished
+	 * 	Called from WSchedule after WAssignmentDialog finished
 	 * 	@param assignment New/Changed Assignment
 	 */
 	public void mAssignmentCallback (MResourceAssignment assignment)
@@ -403,25 +380,89 @@ public class InfoSchedule extends Window implements EventListener //, ChangeList
 			displayCalendar();
 		}
 		//
-		else if (event.getTarget() == fieldResource || event.getTarget() == fieldDate)
-			displayCalendar();
-		//
-		else if (event.getTarget() == bPrevious)
-			adjustDate(-1);
-		else if (event.getTarget() == bNext)
-			adjustDate(+1);
-		else if (event.getTarget().getId().equals("Add"))
+		else if (event.getTarget().getId().equals("New"))
 			doAdd();
 		//
 		
 	}
 
 	private void doAdd() {
-		// TODO Auto-generated method stub
+		ListItem listItem = fieldResource.getSelectedItem();
+		if (listItem == null)
+			return;
+		//	Get Resource Type
+		KeyNamePair pp = new KeyNamePair((Integer)listItem.getValue(), listItem.getLabel());
+		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 ();
+		
+		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;
+					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) {
+			MResourceAssignment ma = new MResourceAssignment(Env.getCtx(), 0, null);
+			ma.setS_Resource_ID(S_Resource_ID);
+			
+			ma.setAssignDateFrom(TimeUtil.getDayTime(start, slot.getStartTime()));
+			ma.setQty(new BigDecimal(1));
+			WAssignmentDialog vad =  new WAssignmentDialog (ma, false, m_createNew);
+			mAssignmentCallback(vad.getMResourceAssignment());		
+		} else {
+			FDialog.error(0, this, "No available time slot for the selected day.");
+		}
 	}
 
+	public boolean isCreateNew() {
+		return m_createNew;
+	}
 
+	/**
+	 * Callback from WSchedule
+	 * @param date
+	 */
+	public void dateCallback(Date date) {
+		m_dateFrom = new Timestamp(date.getTime());
+	}
+	
 
 	/**
 SELECT o.DocumentNo, ol.Line, ol.Description
diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/window/WAssignmentDialog.java b/zkwebui/WEB-INF/src/org/adempiere/webui/window/WAssignmentDialog.java
new file mode 100644
index 0000000000..19263f45a4
--- /dev/null
+++ b/zkwebui/WEB-INF/src/org/adempiere/webui/window/WAssignmentDialog.java
@@ -0,0 +1,412 @@
+/******************************************************************************
+ * Product: Adempiere ERP & CRM Smart Business Solution                        *
+ * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved.                *
+ * 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.                     *
+ * For the text or an alternative of this public license, you may reach us    *
+ * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA        *
+ * or via info@compiere.org or http://www.compiere.org/license.html           *
+ *****************************************************************************/
+package org.adempiere.webui.window;
+
+import java.math.*;
+import java.sql.*;
+import java.util.*;
+import java.util.Date;
+import java.util.logging.*;
+
+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;
+import org.adempiere.webui.component.Grid;
+import org.adempiere.webui.component.Label;
+import org.adempiere.webui.component.ListItem;
+import org.adempiere.webui.component.Listbox;
+import org.adempiere.webui.component.NumberBox;
+import org.adempiere.webui.component.Row;
+import org.adempiere.webui.component.Rows;
+import org.adempiere.webui.component.Textbox;
+import org.adempiere.webui.component.Window;
+import org.compiere.model.*;
+import org.compiere.util.*;
+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.Timebox;
+
+/**
+ *	Resource Assignment Dialog
+ *
+ * 	@author 	Jorg Janke
+ * 	@version 	$Id: VAssignmentDialog.java,v 1.2 2006/07/30 00:51:28 jjanke Exp $
+ * 
+ *  Zk Port
+ *  @author Low Heng Sin
+ */
+public class WAssignmentDialog extends Window implements EventListener
+{
+	/**
+	 * 	Assignment Dialog.
+	 * 	
+	 * 		Creates a new assignment oor displays an assignment
+	 * 		Create new:	(ID == 0)
+	 * 			check availability & create assignment
+	 * 			(confirmed when order/incoice/timeExpense is processed)
+	 * 			alternatively let InfoResource do the assignment
+	 * 			return ID
+	 * 		Existing assignment: (ID != 0)
+	 * 			if confirmed - no change.
+	 * 			ability to delete or change assignment
+	 * 			return ID
+	 * 	
+ * @param mAssignment Assignment + * @param allowZoom allow to zoom to schedule + * @param allowDelete allow to delete recorde + */ + public WAssignmentDialog (MResourceAssignment mAssignment, + boolean allowZoom, boolean allowDelete) + { + super (); + this.setTitle(Msg.getMsg(Env.getCtx(), "VAssignmentDialog")); + this.setAttribute("mode", "modal"); + this.setBorder("normal"); + + log.config(mAssignment.toString()); + m_mAssignment = mAssignment; + try + { + init(); + if (!allowZoom) + confirmPanel.getButton("Zoom").setVisible(false); + delete.setVisible(allowDelete); + } + catch(Exception e) + { + log.log(Level.SEVERE, "", e); + } + setDisplay(); // from mAssignment + // + AEnv.showWindow(this); + } // VAssignmentDialog + + /** Assignment */ + private MResourceAssignment m_mAssignment; + /** True if setting Value */ + private boolean m_setting = false; + /** Logger */ + private static CLogger log = CLogger.getCLogger(WAssignmentDialog.class); + /** Lookup with Resource & UOM */ + private HashMap m_lookup = new HashMap(); + + // + private Grid mainPanel = new Grid(); + private Label lResource = new Label(Msg.translate(Env.getCtx(), "S_Resource_ID")); + private Listbox fResource = new Listbox(getResources()); + private Label lDate = new Label(Msg.translate(Env.getCtx(), "DateFrom")); + 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 Label lUOM = new Label(); + private Label lName = new Label(Msg.translate(Env.getCtx(), "Name")); + private Label lDescription = new Label(Msg.translate(Env.getCtx(), "Description")); + private Textbox fName = new Textbox(); + 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; + + /** + * Static Init + * @throws Exception + */ + private void init() throws Exception + { + fResource.setMold("select"); + fResource.addEventListener(Events.ON_SELECT, this); + delete.addEventListener(Events.ON_CLICK, this); + confirmPanel.addComponentsLeft(delete); + confirmPanel.addActionListener(Events.ON_CLICK, this); + // + this.appendChild(mainPanel); + mainPanel.makeNoStrip(); + mainPanel.setStyle("background-color: transparent"); + + Rows rows = new Rows(); + mainPanel.appendChild(rows); + Row row = new Row(); + row.appendChild(LayoutUtils.makeRightAlign(lResource)); + row.appendChild(fResource); + row.appendChild(new Label(" ")); + rows.appendChild(row); + + row = new Row(); + row.setSpans("1, 2"); + row.appendChild(LayoutUtils.makeRightAlign(lDate)); + Div div = new Div(); + div.appendChild(fDateFrom); + div.appendChild(fTimeFrom); + fTimeFrom.setStyle("margin-left: 5px"); + row.appendChild(div); + rows.appendChild(row); + + row = new Row(); + row.appendChild(LayoutUtils.makeRightAlign(lQty)); + row.appendChild(fQty); + row.appendChild(lUOM); + rows.appendChild(row); + + row = new Row(); + row.setSpans("1, 2"); + row.appendChild(LayoutUtils.makeRightAlign(lName)); + row.appendChild(fName); + fName.setStyle("width: 100%"); + rows.appendChild(row); + + row = new Row(); + row.setSpans("1, 2"); + row.appendChild(LayoutUtils.makeRightAlign(lDescription)); + row.appendChild(fDescription); + fDescription.setMultiline(true); + fDescription.setRows(3); + fDescription.setStyle("width: 100%"); + rows.appendChild(row); + + row = new Row(); + row.setSpans("3"); + row.appendChild(new Label(" ")); + rows.appendChild(row); + + row = new Row(); + row.setSpans("3"); + row.appendChild(confirmPanel); + rows.appendChild(row); + // + } // jbInit + + /** + * Initialize component & values from m_mAssignment + */ + private void setDisplay() + { + m_setting = true; + + // Set Resource + int S_Resource_ID = m_mAssignment.getS_Resource_ID(); + KeyNamePair[] resources = new KeyNamePair[m_lookup.size()]; + m_lookup.keySet().toArray(resources); + for (int i = 0; i < resources.length; i++) + { + if (resources[i].getKey() == S_Resource_ID) + { + fResource.setSelectedIndex(i); + break; + } + } + ListItem listItem = fResource.getSelectedItem(); + KeyNamePair check = new KeyNamePair((Integer)listItem.getValue(), listItem.getLabel()); + if (check == null || check.getKey() != S_Resource_ID) + { + if (m_mAssignment.getS_ResourceAssignment_ID() == 0) // new record select first + fResource.setSelectedItem(fResource.getSelectedItem()); // initiates UOM display + else + log.log(Level.SEVERE, "Resource not found ID=" + S_Resource_ID); + } + + // Set Date, Qty + fDateFrom.setValue(m_mAssignment.getAssignDateFrom()); + fTimeFrom.setValue(m_mAssignment.getAssignDateFrom()); + fQty.setValue(m_mAssignment.getQty()); + + // Name, Description + fName.setValue(m_mAssignment.getName()); + fDescription.setValue(m_mAssignment.getDescription()); + + // Set Editor to R/O if confirmed + boolean readWrite = true; + if (m_mAssignment.isConfirmed()) + readWrite = false; + confirmPanel.getButton("Cancel").setVisible(readWrite); + fResource.setEnabled(readWrite); + fDateFrom.setReadonly(!readWrite); + fQty.setReadonly(!readWrite); + + m_setting = false; + } // dynInit + + /************************************************************************** + * Get Assignment + * @return Assignment + */ + public MResourceAssignment getMResourceAssignment() + { + return m_mAssignment; + } // getMResourceAssignment + + + /** + * Check availability and insert record + * @return true if saved/updated + */ + private boolean cmd_save() + { + log.config(""); + // Set AssignDateTo + Calendar date = new GregorianCalendar(); + getDateAndTimeFrom(date); + Timestamp assignDateFrom = new Timestamp(date.getTimeInMillis()); + BigDecimal qty = new BigDecimal(fQty.getValue()); + KeyNamePair uom = (KeyNamePair)m_lookup.get(fResource.getSelectedItem()); + int minutes = MUOMConversion.convertToMinutes(Env.getCtx(), uom.getKey(), qty); + Timestamp assignDateTo = TimeUtil.addMinutess(assignDateFrom, minutes); + m_mAssignment.setAssignDateTo (assignDateTo); + // + // m_mAssignment.dump(); + return m_mAssignment.save(); + } // cmdSave + + + /************************************************************************** + * Load Resources. + * called from variable constructor + * @return Array with resources + */ + private KeyNamePair[] getResources() + { + if (m_lookup.size() == 0) + { + String sql = MRole.getDefault().addAccessSQL( + "SELECT r.S_Resource_ID, r.Name, r.IsActive," // 1..3 + + "uom.C_UOM_ID,uom.UOMSymbol " // 4..5 + + "FROM S_Resource r, S_ResourceType rt, C_UOM uom " + + "WHERE r.S_ResourceType_ID=rt.S_ResourceType_ID AND rt.C_UOM_ID=uom.C_UOM_ID", + "r", MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO); + try + { + PreparedStatement pstmt = DB.prepareStatement(sql, null); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) + { + StringBuffer sb = new StringBuffer (rs.getString(2)); + if (!"Y".equals(rs.getString(3))) + sb.insert(0,'~').append('~'); // inactive marker + // Key S_Resource_ID/Name + KeyNamePair key = new KeyNamePair (rs.getInt(1), sb.toString()); + // Value C_UOM_ID/Name + KeyNamePair value = new KeyNamePair (rs.getInt(4), rs.getString(5).trim()); + m_lookup.put(key, value); + } + rs.close(); + pstmt.close(); + } + catch (SQLException e) + { + log.log(Level.SEVERE, sql, e); + } + } + // Convert to Array + KeyNamePair[] retValue = new KeyNamePair[m_lookup.size()]; + m_lookup.keySet().toArray(retValue); + Arrays.sort(retValue); + return retValue; + } // getResources + + public void onEvent(Event e) throws Exception { + if (m_setting) + return; + // Update Assignment + ListItem listItem = fResource.getSelectedItem(); + KeyNamePair resource = listItem != null ? new KeyNamePair((Integer)listItem.getValue(), listItem.getLabel()) : null; + if (resource != null) + { + int S_Resource_ID = resource.getKey(); + m_mAssignment.setS_Resource_ID (S_Resource_ID); + } + + Calendar date = new GregorianCalendar(); + getDateAndTimeFrom(date); + + Timestamp assignDateFrom = new Timestamp(date.getTimeInMillis()); + if (assignDateFrom != null) + m_mAssignment.setAssignDateFrom (assignDateFrom); + if (fQty.getValue() != null && fQty.getValue().trim().length() > 0) { + BigDecimal qty = new BigDecimal(fQty.getValue()); + m_mAssignment.setQty(qty); + } + m_mAssignment.setName((String)fName.getValue()); + m_mAssignment.setDescription((String)fDescription.getValue()); + + // Resource - Look up UOM + if (e.getTarget() == fResource) + { + Object o = m_lookup.get(fResource.getSelectedItem()); + if (o == null) + lUOM.setValue(" ? "); + else + lUOM.setValue(o.toString()); + } + + // Zoom - InfoResource + else if (e.getTarget().getId().equals("Zoom")) + { + InfoSchedule is = new InfoSchedule (m_mAssignment, true); + if (is.getMResourceAssignment() != null) + { + m_mAssignment = is.getMResourceAssignment(); + // setDisplay(); + detach(); + } + is = null; + } + + // cancel - return + else if (e.getTarget().getId().equals("Cancel")) + { + m_cancel = true; + detach(); + } + + // delete - delete and return + else if (e.getTarget().getId().equals("Delete")) + { + if (m_mAssignment.delete(true)) + { + m_mAssignment = null; + detach(); + } + else + FDialog.error(0, this, "ResourceAssignmentNotDeleted"); + } + + // OK - Save + else if (e.getTarget().getId().equals("Ok")) + { + if (cmd_save()) + detach(); + } + } + + private void getDateAndTimeFrom(Calendar date) { + Date dateFrom = fDateFrom.getValue(); + Date timeFrom = fTimeFrom.getValue(); + date.setTime(dateFrom); + Calendar time = new GregorianCalendar(); + time.setTime(timeFrom); + date.set(Calendar.HOUR, time.get(Calendar.HOUR)); + date.set(Calendar.MINUTE, time.get(Calendar.MINUTE)); + } + + public boolean isCancelled() { + return m_cancel; + } +} // VAssignmentDialog diff --git a/zkwebui/js/layout.js b/zkwebui/js/layout.js index b685a7ce6e..ddee6f869b 100644 --- a/zkwebui/js/layout.js +++ b/zkwebui/js/layout.js @@ -10,3 +10,11 @@ function _ad_deferBDL(uuid) { zk.onSizeAt(); zkau.getMeta($e(uuid)).render(); } + +function ad_closeBuble(uuid) { + var cmp = $e(uuid); + for(i=0;i