/****************************************************************************** * Copyright (C) 2012 Trek Global * * Product: iDempiere ERP & CRM Smart Business Solution * * 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.panel; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.Hashtable; import java.util.logging.Level; import org.adempiere.exceptions.DBException; import org.adempiere.model.MBroadcastMessage; import org.adempiere.webui.ClientInfo; import org.adempiere.webui.component.Button; import org.adempiere.webui.component.Checkbox; import org.adempiere.webui.component.Label; import org.adempiere.webui.component.Window; import org.adempiere.webui.util.ZKUpdateUtil; import org.compiere.model.MNote; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.Util; import org.idempiere.broadcast.IBroadcastMsgPopup; import org.zkoss.zk.ui.Component; 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.Borderlayout; import org.zkoss.zul.Cell; import org.zkoss.zul.Center; import org.zkoss.zul.Div; import org.zkoss.zul.Hbox; import org.zkoss.zul.Html; import org.zkoss.zul.North; import org.zkoss.zul.Separator; import org.zkoss.zul.South; /** * Window to view and acknowledge messages from AD_BroadcastMessage * @author Vivek * @author Deepak Pansheriya * */ public class BroadcastMessageWindow extends Window implements IBroadcastMsgPopup,EventListener{ /** * generated serial id */ private static final long serialVersionUID = 1849434312706721390L; private static final CLogger log = CLogger.getCLogger(BroadcastMessageWindow.class); public static final int PRESSED_PREV = 1; public static final int PRESSED_NEXT = 2; public static final int UPDATE_CurrMsg = 0; /** index of current show/render message in {@link #mbMessages} */ private int currMsg=0; private Label textMsgNo = null; private Html textMsgContent = null; private North north =null; /** Container for message navigation controls */ private Div swDiv =null; private Button btnPrev = null; private Button btnNext = null; private Checkbox acknowledged = null; private ArrayList mbMessages = null; /** AD_BroadcastMessage_ID:Processed */ private Hashtable hashMessages = new Hashtable(); /** Parent of window */ private HeaderPanel pnlHead = null; private boolean isTest = false; private boolean initialised = false; /** * @param pnlHead */ public BroadcastMessageWindow(HeaderPanel pnlHead) { this.pnlHead = pnlHead; textMsgNo = new Label(); textMsgContent = new Html(); textMsgContent.setStyle("color:black;"); btnPrev = new Button("<"); btnNext = new Button(">"); } /** * Layout window */ private void init() { Borderlayout layout = new Borderlayout(); this.appendChild(layout); addEventListener("onFocus", this); initialised = true; String percent; if (ClientInfo.isMobile()) percent = "50%"; else percent = "30%"; ZKUpdateUtil.setWidth(this, percent); ZKUpdateUtil.setHeight(this, percent); setPosition("right,bottom"); setBorder(true); setShadow(false); doOverlapped(); setClosable(true); setSizable(true); setMaximizable(true); north = new North(); layout.appendChild(north); Center center = new Center(); layout.appendChild(center); Div htmlDiv = new Div(); htmlDiv.appendChild(textMsgContent); center.setAutoscroll(true); Env.setContext(Env.getCtx(), MBroadcastMessage.CLIENTINFO_BROADCAST_COMPONENT_ID, pnlHead.getUuid()); setTitle(mbMessages.get(0)); textMsgContent.setContent(mbMessages.get(0).get_Translation(MBroadcastMessage.COLUMNNAME_BroadcastMessage)); htmlDiv.setFocus(true); htmlDiv.setStyle("display: table-cell; vertical-align: middle; text-align: center;"); Div divAlign = new Div(); divAlign.setStyle("color:white; position: absolute; height: 120px; display: table;"); htmlDiv.setParent(divAlign); center.appendChild(divAlign); center.setBorder("rounded"); center.setStyle("-moz-border-radius: 3px; -webkit-border-radius: 3px; border: 1px solid #BBBBBB; border-radius: 3px; margin-bottom:10px;"); South south = new South(); layout.appendChild(south); Hbox southHLayout = new Hbox(); south.appendChild(southHLayout); southHLayout.setSpacing("30"); ZKUpdateUtil.setHflex(southHLayout, "1"); Cell leftCell = new Cell(); southHLayout.appendChild(leftCell); ZKUpdateUtil.setHflex(leftCell, "1"); leftCell.setAlign("center"); swDiv = new Div(); swDiv.setParent(leftCell); acknowledged = new Checkbox(); //createHashTable(); currMsg = 0; btnPrev.addEventListener("onClick", this); btnNext = new Button(">"); btnNext.addEventListener("onClick", this); swDiv.appendChild(btnPrev); swDiv.appendChild(new Separator("vertical")); swDiv.appendChild(textMsgNo); swDiv.appendChild(new Separator("vertical")); swDiv.appendChild(btnNext); textMsgNo.setStyle("font-weight:bold;"); renderMsg(UPDATE_CurrMsg); if(mbMessages.size()<=0) swDiv.setVisible(false); ZKUpdateUtil.setHeight(south, "22%"); acknowledged.setParent(leftCell); acknowledged.setLabel(Msg.getMsg(Env.getCtx(),"Acknowledge")); acknowledged.addEventListener("onClick", this); } private void createHashTable() { hashMessages.clear(); for(int i=0; i arrMessages){ mbMessages = arrMessages; createHashTable(); if(!initialised) init(); pnlHead.appendChild(this); } /** * Append message to existing message list * @param mbMessage * @param isTest */ public void appendMessage(MBroadcastMessage mbMessage, boolean isTest){ this.isTest = isTest; currMsg = 0; if(mbMessages!=null && isTest){ mbMessages.clear(); }else if(mbMessages == null){ mbMessages = new ArrayList(); } mbMessages.add(0, mbMessage); if(!isTest) createHashTable(); if(!initialised) init(); else if(!isTest){ currMsg=0; renderMsg(UPDATE_CurrMsg); } pnlHead.appendChild(this); } @Override public void onEvent(Event event) throws Exception { Component comp = event.getTarget(); int noOfMsgs = mbMessages.size(); if(event.getName().equals(Events.ON_CLICK)){ if(comp == btnPrev){ if(currMsg > 0){ currMsg--; renderMsg(PRESSED_PREV); } }else if (comp == btnNext){ if(currMsg < noOfMsgs-1){ currMsg++; renderMsg(PRESSED_NEXT); } }else if(comp == acknowledged){ hashMessages.put(mbMessages.get(currMsg).get_ID(), acknowledged.isChecked()); } } } /** * Update message on window * @param status next, previous or current */ public void renderMsg(int status) { int msgToUpdate = currMsg-1; if(status == PRESSED_NEXT){ msgToUpdate = currMsg-1; }else if(status == PRESSED_PREV){ msgToUpdate = currMsg+1; }else if(status == UPDATE_CurrMsg){ msgToUpdate = currMsg; } int noOfMsgs = mbMessages.size(); MBroadcastMessage mbMessage = mbMessages.get(currMsg); String broadcastFrequency = mbMessage.getBroadcastFrequency(); if(mbMessages.size()>1) swDiv.setVisible(true); else swDiv.setVisible(false); if (noOfMsgs > 1) { btnNext.setEnabled(true); btnPrev.setEnabled(true); MBroadcastMessage prevMsg = mbMessages.get(msgToUpdate); if((prevMsg.getBroadcastFrequency().equals("J") || prevMsg.getBroadcastType().equals(MBroadcastMessage.BROADCASTTYPE_Immediate))){ hashMessages.put(prevMsg.get_ID(), true); } if (currMsg == 0) { btnPrev.setEnabled(false); } else if (currMsg == noOfMsgs - 1) { if ((broadcastFrequency.equals("J")) || (mbMessage.getBroadcastType().equals(MBroadcastMessage.BROADCASTTYPE_Immediate))) { hashMessages.put(mbMessage.get_ID(), true); } btnNext.setEnabled(false); } } textMsgNo.setValue((currMsg+1)+"/"+noOfMsgs); setTitle(mbMessage); textMsgContent.setContent(mbMessage.get_Translation(MBroadcastMessage.COLUMNNAME_BroadcastMessage)); if (!isTest && mbMessage.isLogAcknowledge()) { boolean ack = hashMessages.get(mbMessage.get_ID()); acknowledged.setChecked(ack); acknowledged.setVisible(true); } else if(mbMessage.isLogAcknowledge()) { acknowledged.setVisible(true); } else if ( broadcastFrequency.equals(MBroadcastMessage.BROADCASTFREQUENCY_JustOnce) || mbMessage.getBroadcastType().equals(MBroadcastMessage.BROADCASTTYPE_Immediate)) { acknowledged.setVisible(false); hashMessages.put(mbMessages.get(currMsg).get_ID(), true); } else { acknowledged.setVisible(false); } } /** * Get AD Note entries for current login user for provided message * @param mbMessage * @return */ public MNote getMNote(MBroadcastMessage mbMessage) { MNote note =null; if(!mbMessage.getBroadcastType().equals(MBroadcastMessage.BROADCASTTYPE_Immediate)){ String sql = "SELECT * FROM AD_Note WHERE AD_BroadcastMessage_ID = ? AND AD_User_ID = ? AND AD_Client_ID in (?, 0)"; PreparedStatement pstmt = null; ResultSet rs=null; try { pstmt = DB.prepareStatement(sql, null); pstmt.setInt(1, mbMessage.get_ID()); pstmt.setInt(2, Env.getAD_User_ID(Env.getCtx())); pstmt.setInt(3, Env.getAD_Client_ID(Env.getCtx())); rs = pstmt.executeQuery(); if(rs.next()) note = new MNote(Env.getCtx(), rs, null); } catch (Exception e) { log.log(Level.SEVERE, "Note for the Message Could not be retrieved ",e); throw new DBException(e); }finally{ DB.close(rs, pstmt); } } return note; } @Override public void onClose() { super.onClose(); if (!isTest) { if(mbMessages.size()==1){ if ((mbMessages.get(0).getBroadcastFrequency().equals(MBroadcastMessage.BROADCASTFREQUENCY_JustOnce)) || (mbMessages.get(0).getBroadcastFrequency().equals(MBroadcastMessage.BROADCASTFREQUENCY_UntilExpiration)) || (mbMessages.get(0).getBroadcastType().equals(MBroadcastMessage.BROADCASTTYPE_Immediate))) { hashMessages.put(mbMessages.get(0).get_ID(), true); } } ArrayList acknowedgedMsgs = new ArrayList(); for (MBroadcastMessage mbMessage : mbMessages) { if(!mbMessage.getBroadcastType().equals(MBroadcastMessage.BROADCASTTYPE_Immediate)){ MNote note = getMNote(mbMessage); if (mbMessage.getBroadcastFrequency().equals(MBroadcastMessage.BROADCASTFREQUENCY_UntilExpiration)) note.setProcessed(true); else note.setProcessed(hashMessages.get(mbMessage.get_ID())); if(hashMessages.get(mbMessage.get_ID())){ acknowedgedMsgs.add(mbMessage); } note.saveEx(); }else{ acknowedgedMsgs.add(mbMessage); } } for (MBroadcastMessage mBroadcastMessage : acknowedgedMsgs) { mbMessages.remove(mBroadcastMessage); } } } /** Set the title for the panel using what is defined on the message or fallback to "Message" */ protected void setTitle(MBroadcastMessage bm) { String title = bm.get_Translation(MBroadcastMessage.COLUMNNAME_Title); setTitle(Util.isEmpty(title) ? Msg.getMsg(Env.getCtx(), "Message") : title); } }