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