001 package market; 002 003 import java.awt.Rectangle; 004 005 import market.event.OfferEventListener; 006 import market.stdform.ButtonIDs; 007 import market.stdform.FSCustomerDefault; 008 import market.stdform.MSLogOff; 009 import sale.Action; 010 import sale.FormSheet; 011 import sale.FormSheetContentCreator; 012 import sale.MenuSheet; 013 import sale.SaleProcess; 014 import sale.SalesPoint; 015 import sale.Shop; 016 import users.User; 017 import data.CountingStock; 018 import data.DataBasketCondition; 019 import data.DataBasketEntry; 020 import data.DataBasketEntryDestination; 021 import data.DataBasketEntrySource; 022 023 /** 024 * SalesPoint used by the {@link UCustomer}. 025 */ 026 public class SPCustomer extends SPListenable implements OfferEventListener{ 027 028 /** 029 * ID for serialization. 030 */ 031 private static final long serialVersionUID = -4380520617845209584L; 032 /** 033 * Array with all SPCustomers used to fire events to 034 */ 035 private static OfferEventListener[] oel = new OfferEventListener[0]; 036 037 /** 038 * @param user the User of this SPCustomer 039 */ 040 public SPCustomer(User user){ 041 super("Kundenterminal - "+((UPerson)user).getFullName()); 042 this.attach(user); 043 this.setSalesPointFrameBounds(new Rectangle(0,0,640,540)); 044 SMarket.addEventListener((market.event.MarketEventListener)this); 045 SPCustomer.addEventListener(this); 046 Shop.getTheShop().addSalesPoint(this); 047 } 048 049 050 //###################################### SalesPoint ############################################# 051 052 /** 053 * @return <code>true</code> if no SaleProcess is running, otherwise <code>false</code>. 054 * This forces the user to quit the SaleProcess before he closes the SalesPoint. 055 */ 056 protected boolean onCanQuit(){ 057 return getCurrentProcess() == null; 058 } 059 060 /** 061 * Removes this SPSustomer from the array of OfferEventListeners. 062 */ 063 public void quit() { 064 SPCustomer.removeEventListener(this); 065 super.quit(); 066 } 067 068 /** 069 * @return the default FormSheet 070 */ 071 protected FormSheet getDefaultFormSheet() { 072 FormSheet sheet = new FSCustomerDefault(); 073 sheet.addContentCreator(new FormSheetContentCreator(){ 074 private static final long serialVersionUID = 1146704984018039866L; 075 protected void createFormSheetContent(FormSheet fs) { 076 fs.getButton(ButtonIDs.BTN_BUY).setAction(buyAction()); 077 fs.getButton(ButtonIDs.BTN_EDIT).setAction(editAction()); 078 } 079 }); 080 return sheet; 081 } 082 083 /** 084 * @return the default MenuSheet 085 */ 086 protected MenuSheet getDefaultMenuSheet() { 087 return new MSLogOff(); 088 } 089 090 091 //################################### our methods ###################################################### 092 093 /** 094 * @return an Action that initiates a SProcessBuy on this Salespoint, 095 * if the customer already contains to the till-queue or the market is to be closed 096 * it will pop up an error-message. 097 */ 098 private Action buyAction(){ 099 return new Action(){ 100 private static final long serialVersionUID = 3439946422782505800L; 101 public void doAction(SaleProcess p, SalesPoint sp) throws Throwable { 102 User user = sp.getUser(); 103 boolean error = false; 104 String errorMsg = ""; 105 String errorCaption = ""; 106 if (SMarket.isToBeClosed()) { 107 error = true; 108 errorMsg = SMarket.MARKET_CLOSES_LONG; 109 errorCaption = "Feierabend"; 110 } 111 if(SMarket.getTillQueue().contains(user.getName(), null)) { 112 error = true; 113 errorMsg = "Sie haben bereits eine Auswahl von Artikeln in Auftrag gegeben!\n"+ 114 "Bitte begeben Sie sich zunächst zur Kasse, um diesen Autrag abzuschliessen!"; 115 errorCaption = "Auftrag abschließen"; 116 } 117 if (error) { 118 JDDShowMessage.showMessageDialog(sp.getDisplay().getFormSheet(), errorMsg, 119 errorCaption); 120 } else { 121 sp.runProcess(new SProcessCustomer(user)); 122 } 123 } 124 }; 125 } 126 127 /** 128 * @return an Action that initiates a SProcessCustomerEditProfile on this SalesPoint, 129 * taking the customer attached to this SPCustomer as argument. 130 */ 131 private Action editAction(){ 132 return new Action(){ 133 private static final long serialVersionUID = 8721124416084580882L; 134 public void doAction(SaleProcess p, SalesPoint sp) throws Throwable { 135 boolean error = false; 136 String errorMsg = ""; 137 String errorCaption = ""; 138 if (SMarket.isToBeClosed()) { 139 error = true; 140 errorMsg = SMarket.MARKET_CLOSES_LONG; 141 errorCaption = "Feierabend"; 142 } 143 if (error) { 144 JDDShowMessage.showMessageDialog(sp.getDisplay().getFormSheet(), errorMsg, 145 errorCaption); 146 } else { 147 sp.runProcess(new SProcessCustomerEditProfile(sp.getUser())); 148 } 149 } 150 }; 151 } 152 153 154 //////////////////////////////////////////////////////////////// 155 // Event handling 156 //////////////////////////////////////////////////////////////// 157 158 /** 159 * Adds an OfferEventListener to the array of listeners. 160 * 161 * @param e the OfferEventListener that will be added. 162 */ 163 public static void addEventListener(OfferEventListener e){ 164 int len = oel.length; 165 boolean exists = false; 166 for (int i = 0; i < len; i++) { 167 exists = exists || (oel[i] == e); 168 } 169 if (!exists) { 170 OfferEventListener[] temp = new OfferEventListener[len+1]; 171 System.arraycopy(oel, 0, temp, 0, len); 172 temp[len] = e; 173 oel = temp; 174 } 175 } 176 177 /** 178 * Removes an OfferEventListener from the array of listeners. 179 * 180 * @param e the OfferEventListener that will be removed. 181 */ 182 public static void removeEventListener(OfferEventListener e){ 183 for (int i = 0; i < oel.length; i++) { 184 if (oel[i] == e) { 185 OfferEventListener[] temp = new OfferEventListener[oel.length-1]; 186 if (i > 0) System.arraycopy(oel,0,temp,0,i); 187 if (i < oel.length-1) System.arraycopy(oel,i+1,temp,i,oel.length-1-i); 188 oel = temp; 189 break; 190 } 191 } 192 } 193 194 /** 195 * Fires an event to all listeners: this article is empty. 196 * 197 * @param articleKey the key of the unavailable article. 198 */ 199 public static void fireOfferIsEmpty(String articleKey) { 200 for (int i = 0; i < oel.length; i++) { 201 if (oel[i] != null) oel[i].offerEmpty(articleKey); 202 } 203 } 204 205 /** 206 * Fires an event to all listeners: count this article. 207 * 208 * @param articleKey the key of the article to count. 209 * @param spw the SProcessWorker which has sended the request. 210 */ 211 public static void fireCountArticles(String articleKey, SProcessWorker spw){ 212 for (int i = 0; i < oel.length; i++) { 213 if (oel[i] != null) oel[i].countArticles(articleKey, spw); 214 } 215 } 216 217 /** 218 * Reaction on event: An article is unavailable. 219 * 220 * @param articleKey the unavailable article. 221 */ 222 public void offerEmpty(final String articleKey) { 223 CountingStock cs = ((UCustomer)this.getUser()).getShoppingBasket(); 224 if(this.getCurrentProcess() instanceof SProcessCustomer && 225 cs.contains(articleKey, this.getBasket())){ 226 this.getBasket().rollback(new DataBasketCondition(){ 227 private static final long serialVersionUID = 2899752284804079449L; 228 public String getMainKey() { 229 return null; 230 } 231 public String getSecondaryKey() { 232 return null; 233 } 234 public DataBasketEntrySource getSource() { 235 return null; 236 } 237 public DataBasketEntryDestination getDestination() { 238 return null; 239 } 240 public Object getValue() { 241 return null; 242 } 243 public boolean match(DataBasketEntry dbe) { 244 if(dbe.getSecondaryKey().compareTo(articleKey)==0) return true; 245 return false; 246 } 247 }); 248 try { 249 this.getCurrentProcess().suspend(); 250 } catch (InterruptedException e) { 251 } 252 JDDShowMessage.showMessageDialog(getDisplay().getFormSheet(), 253 "Aufgrund einer Bestandskorrektur musste folgender Artikel: "+ 254 SMarket.getArticleCatalog().get(articleKey).getArticleName()+ 255 " aus ihrem Einkaufskorb entfernt werden.\n" + 256 "Bitte wählen sie neu.", "Artikel nicht verfügbar! "+ 257 ((UPerson)this.getUser()).getFullName()); 258 } 259 } 260 261 /** 262 * Empty implementation of the OfferEventListener Interface. 263 */ 264 public void wakeUpOrders() { 265 } 266 267 /** 268 * Reaction on event: a SProcessWorker needs the count of all existing articles. 269 * 270 * @param articleKey the name of the article. 271 * @param spw the SProcessWorker that sends the request. 272 */ 273 public void countArticles(String articleKey, SProcessWorker spw) { 274 int count = 0; 275 if(this.getCurrentProcess() instanceof SProcessCustomer && 276 ((UCustomer)this.getUser()).getShoppingBasket().contains(articleKey, this.getBasket())){ 277 count = ((UCustomer)this.getUser()).getShoppingBasket().countItems(articleKey, this.getBasket()); 278 spw.addDatabaseCount(count, SProcessWorker.BUYPROCESS); 279 } 280 } 281 }