001    import sale.*;
002    import sale.stdforms.*;
003    import data.*;
004    import data.ooimpl.*;
005    import data.stdforms.*;
006    import data.events.*;
007    import users.*;
008    import log.*;
009    
010    import java.util.*;
011    import java.text.*;
012    import java.lang.*;
013    import java.io.*;
014    
015    import javax.swing.JTextField;
016    import javax.swing.JPanel;
017    import javax.swing.JOptionPane;
018    import javax.swing.BoxLayout;
019    import javax.swing.JLabel;
020    
021    
022    
023    /**
024     * Rückgabeprocess, der von einem registrierten Kunden
025     * am Automaten durchgeführt werden kann.
026     */
027    public class GiveBackProcess extends SaleProcess
028    {
029       
030      //// attributes ////////////////////////////////////////////////////////////
031       
032      // Gates
033      protected UIGate capabilityGate;
034      protected UIGate selectionGate;
035      protected UIGate giveRestGate;
036      
037      // Transitions
038      protected Transition toSelectionTransition;
039      protected Transition toGetMoneyTransition;
040      
041      // verwendete Waehrung
042      protected Currency myCurrency;
043       
044      // rueckzuzahlender Betrag
045      private int toPayBackValue;
046       
047      // gezahlter Betrag (Verkaufspreis des Videos)
048      private IntegerValue paidValue;
049       
050      // Kunde, der zurueckgeben moechte
051      private Customer customer;
052       
053      // Verleihpreis eines Videos pro Tag
054      private int rentPrice = 300;
055       
056       
057      //// constructor ///////////////////////////////////////////////////////////
058       
059      /**
060       * Erzeugt ein neues Objekt der Klasse GiveBackProcess.
061       */
062      public GiveBackProcess()
063      {
064        super ("GiveBackProcess");
065      }
066       
067      //// protected methods /////////////////////////////////////////////////////
068       
069      /**
070       * Baut die Oberfläche für den Rückgabevorgang auf.
071       */
072      protected void setupMachine()
073      {
074        // verwendete Waehrung ermitteln
075        myCurrency = (Currency)Shop.getTheShop().getCatalog("DM");
076          
077        // Videokatalog
078        final CatalogImpl videoCatalog =
079          (CatalogImpl)Shop.getTheShop().getCatalog("Video-Catalog");
080          
081        // zu verwendenden Datenkorb ermitteln
082        final DataBasket db = getBasket();
083          
084          
085        //////////////////////////////////////////////////
086        /// Capability-Gate //////////////////////////////
087        //////////////////////////////////////////////////
088          
089          
090        // Formsheet fuer Eingabe der Kundennummer
091        // tif ist final, damit in der anonymen Klasse des FSCC auf Attribute des tif zugegriffen werden kann
092        final TextInputForm tif = new TextInputForm("Customer-ID",
093                                                    "Customer-ID",
094                                                    "");
095          
096        // FormSheetContentCreator fuer Capability-Gate implementieren       
097        tif.addContentCreator(
098          new FormSheetContentCreator()
099          {
100            protected void createFormSheetContent(FormSheet fs)
101            {
102              // alle vorhandenen Buttons entfernen
103              fs.removeAllButtons();
104                                        
105              // neuen "OK"-Button einbauen
106              fs.addButton ("Ok", 100, 
107                new sale.Action()
108                {
109                  public void doAction (SaleProcess p, SalesPoint sp)
110                  {
111                    // Eingabe ueberpruefen
112                    String customerID = tif.getText();
113                    boolean isNotAnInteger = true;
114                                                              
115                    try {
116                      new Integer(customerID);
117                      isNotAnInteger = false;
118                    }                                                            
119                    catch (NumberFormatException nfe) {
120                    }
121                    // Eingabe korrekt -> selectionGate
122                    if (!isNotAnInteger && (new Integer(customerID)).intValue() > 0) 
123                    {                                                             
124                      // existiert der Kunde?
125                      try {
126                        boolean customerExists = false;
127                        Set customerSet = VideoMachine.getAllCustomer();
128                        Iterator i = customerSet.iterator();
129                        while (i.hasNext() && !customerExists) 
130                        {
131                          Customer myCustomer = (Customer)i.next();
132                          if (myCustomer.getCustomerID().equals(customerID)) 
133                          {
134                            customer = myCustomer;
135                            customerExists = true;
136                          }
137                        }
138                                                                    
139                        if (customerExists) 
140                        {
141                          capabilityGate.setNextTransition(toSelectionTransition);
142                        }
143                        else 
144                        {
145                          JOptionPane.showMessageDialog(null, "This CustomerID doesn't exist!");
146                          capabilityGate.setNextTransition(
147                            new GateChangeTransition(capabilityGate));
148                        }
149                      }                                                      
150                      catch (NullPointerException ne) {
151                        JOptionPane.showMessageDialog(null, "No videos rent out!");
152                        new GateChangeTransition(capabilityGate);
153                      }
154                    }                                               
155                    // Eingabe falsch -> Kunden informieren und
156                    // Eingabe wiederholen
157                    else 
158                    {
159                      JOptionPane.showMessageDialog(null, "CustomerID must be a positive number!");
160                      capabilityGate.setNextTransition(
161                        new GateChangeTransition(capabilityGate));
162                    }
163                  }
164                }
165              );
166                                        
167              // "Cancel"-Button einbauen
168              fs.addButton ("Cancel", 101, 
169                new sale.Action()
170                  {
171                    public void doAction (SaleProcess p, SalesPoint sp)
172                    {
173                      // Transition zum Rollback-Gate als naechste Transition setzen
174                      capabilityGate.setNextTransition(
175                        GateChangeTransition.CHANGE_TO_ROLLBACK_GATE);
176                    }
177                  }
178              );
179            }
180          }
181        );
182          
183        // Gate zur Kundennummer-Abfrage anlegen
184        capabilityGate = new UIGate((FormSheet) tif, 
185                                    (MenuSheet) null);
186          
187          
188        //////////////////////////////////////////////////
189        /// Selection-Gate ///////////////////////////////
190        //////////////////////////////////////////////////
191          
192          
193        // Auswahl-Gate anlegen
194        // Das FormSheet wird durch die Transition waehrend der Laufzeit erzeugt
195        selectionGate = new UIGate((FormSheet) null, (MenuSheet) null);
196          
197        // Transition zum Selection Gate
198        toSelectionTransition = 
199          new Transition()
200          {
201            public Gate perform(SaleProcess pOwner, User usr)
202            {
203              // zu verwendenden Bestand ermitteln
204              StoringStock ss = customer.getStoringStock();
205                      
206              // am Gate darzustellendes FormSheet
207              TwoTableFormSheet ttfs = 
208                TwoTableFormSheet.create("Give Back",           // Titel des FormSheets
209                                         ss,                    // Quell-StoringStock
210                                         db,                    // Ziel-DataBasket
211                                         selectionGate          // Gate, an dem das FormSheet darzustellen ist
212                                         );
213                      
214              // FormSheetContentCreator am Auswahl-Gate anmelden    
215              ttfs.addContentCreator(
216                new FormSheetContentCreator()
217                {
218                  protected void createFormSheetContent(FormSheet fs)
219                  {
220                    // alle vorhandenen Buttons entfernen
221                    fs.removeAllButtons();
222                                                   
223                    // neuen "OK"-Button einbauen
224                    fs.addButton ("Ok", 100, 
225                      new sale.Action()
226                      {
227                        public void doAction (SaleProcess p, SalesPoint sp)
228                        {
229                          // Transition zum Bezahlen als naechste Transition setzen
230                          selectionGate.setNextTransition(toGetMoneyTransition);
231                        }
232                      }
233                    );
234                                  
235                    // "Cancel"-Button einbauen
236                    fs.addButton ("Cancel", 101, 
237                      new sale.Action()
238                      {
239                        public void doAction (SaleProcess p, SalesPoint sp)
240                        {
241                          // Transition zum Rollback-Gate als naechste Transition setzen
242                          selectionGate.setNextTransition(
243                            GateChangeTransition.CHANGE_TO_ROLLBACK_GATE);
244                        }
245                      }
246                    );
247                  }
248                }
249              );
250                      
251              // erstelltes FormSheet am zu betretenden Gate setzen
252              selectionGate.setFormSheet(ttfs);
253                     
254              // als naechstes zu betretendes Gate zurueckgeben
255              return selectionGate;
256            }
257          };
258          
259          
260        //////////////////////////////////////////////////
261        /// GiveRest-Gate ////////////////////////////////
262        //////////////////////////////////////////////////
263         
264          
265        // Gate zum Ausgeben des Restgeldes anlegen
266        // Das FormSheet wird durch die Transition waehrend der Laufzeit erzeugt
267        giveRestGate = new UIGate(null, null);
268         
269        // Transition zum Gate, an dem das Restgeld gegeben wird
270        toGetMoneyTransition = 
271          new Transition()
272          {
273            public Gate perform(SaleProcess pOwner, User usr)
274            {
275              // Parameter zum Aufsummieren des Datenkorbes festlegen
276              DataBasketCondition dbc =
277                DataBasketConditionImpl.ALL_STOCK_ITEMS;
278              int sellValue = 0;
279              int rentValue = 0;
280                      
281              // Videobestand des Automaten
282              CountingStockImpl videoStock =
283                (CountingStockImpl)Shop.getTheShop().getStock("Video-Countingstock");
284                      
285              // aktuelle Zeit ermitteln
286              Object date = Shop.getTheShop().getTimer().getTime();
287                      
288              // rueckzuzahlenden Betrag ermitteln
289              Iterator i = db.iterator(dbc);
290                
291              while (i.hasNext()) 
292              {         
293                // spezielle Kassette ermitteln
294                StoringStockItemDBEntry cassetteItem = 
295                  (StoringStockItemDBEntry)i.next();
296                CassetteStoringStockItem cassette = 
297                  (CassetteStoringStockItem)cassetteItem.getValue();
298                         
299                // Verkaufspreis bestimmen
300                try {
301                  sellValue =
302                    ((NumberValue)((QuoteValue)(videoCatalog.get(
303                      cassette.getName(), null, false).getValue())).getBid()
304                        ).getValue().intValue();
305                }
306                catch (VetoException ve) {}
307                        
308                // mind. einen Tag ausgeliehen?
309                if ((((Long)date).intValue()
310                  - ((Long)cassette.getDate()).intValue()) > 0) 
311                {
312                  // Verleihgebuehr bestimmen
313                  rentValue = (((Long)date).intValue()
314                    - ((Long)cassette.getDate()).intValue()) * rentPrice;
315                                                   
316                  // Leihgebuehr kleiner als Verkaufspreis?
317                  if (rentValue < sellValue) 
318                  {
319                    //rueckzuzahlenden Betrag erhoehen
320                    toPayBackValue = toPayBackValue + (sellValue - rentValue);
321                               
322                    // Video in Automatenbestand zuruecklegen
323                    videoStock.add(cassette.getName(), 1, null);
324                               
325                    // Vorgang in Logdatei eintragen
326                    try {
327                      Log.getGlobalLog().log(new MyLoggable(cassetteItem,
328                                                            customer, date));
329                    }            
330                    catch (LogNoOutputStreamException lnose) {
331                    }
332                    catch (IOException ioe) {
333                    }
334                  }                           
335                  // Leihgebuehr groesser als Verkaufspreis
336                  else 
337                  {
338                    JOptionPane.showMessageDialog(null,
339                      cassette.getName() + " is your's!");
340                  }                        
341                }
342                         
343                // keinen Tag ausgeliehen (trotzdem 3,00 DM Leihgebuehr)
344                if ((((Long)date).intValue()
345                  - ((Long)cassette.getDate()).intValue()) == 0) 
346                {          
347                  //rueckzuzahlenden Betrag erhoehen
348                  toPayBackValue = toPayBackValue + (sellValue - rentPrice);
349                            
350                  // Video in Automatenbestand zuruecklegen
351                  videoStock.add(cassette.getName(), 1, null);
352                            
353                  // Vorgang in Logdatei eintragen
354                  try {
355                    Log.getGlobalLog().log(new MyLoggable(cassetteItem,
356                                                          customer, date));
357                  }
358                  catch (LogNoOutputStreamException lnose) {
359                  }
360                  catch (IOException ioe) {
361                  }
362                }
363              }
364                      
365              // ueberpruefen, ob der Kunde noch Videos im Bestand hat
366              if (customer.getStoringStock().size(null) == 0)
367                VideoMachine.removeCustomer(customer);
368                      
369              // rueckzugebenden Betrag vom Geldbestand abziehen
370              try 
371              {
372                if (toPayBackValue > 0 ) 
373                {
374                  ((CountingStock)Shop.getTheShop().getStock(
375                     "coin slot")).remove(CurrencyImpl.PFENNIG_STCK_1,
376                        toPayBackValue, pOwner.getBasket());
377                }
378              }
379              catch (VetoException ve) {
380              }
381                     
382              // am Gate darzustellendes FormSheet
383              MsgForm mf = new MsgForm("Give Rest",
384                                       "You get " +
385                                       myCurrency.toString(new IntegerValue(toPayBackValue)) +
386                                       " back");
387                      
388              // ContentCreator zur Neubelegung des "OK"-Buttons hinzufuegen 
389              mf.addContentCreator(
390                new FormSheetContentCreator()
391                {
392                  public void createFormSheetContent(FormSheet fs)
393                  {
394                    // neue Aktion setzen
395                    fs.getButton(FormSheet.BTNID_OK).setAction(
396                      new Action()
397                      {
398                        public void doAction(SaleProcess p, SalesPoint sp)
399                        {
400                        // zum Commit-Gate fuehrende Transition als
401                        // naechste Transition setzen
402                        giveRestGate.setNextTransition(
403                          GateChangeTransition.CHANGE_TO_COMMIT_GATE);
404                        }
405                      }
406                    );
407                  }
408                } 
409             ); 
410                      
411             // erstelltes FormSheet am zu betretenden Gate setzen
412             giveRestGate.setFormSheet(mf);
413                     
414             // als naechstes zu betretendes Gate zurueckgeben
415             return giveRestGate;
416           }
417         };
418       }
419       
420       
421       //// public methods ////////////////////////////////////////////////////////
422       
423       /**
424        * Gibt das Startgate des Prozesses zurück.
425        */
426       public Gate getInitialGate()
427       {  
428         // Automat aufbauen
429         setupMachine();
430          
431         // ...und Capability-Gate als Startgate zurueckgeben
432         return capabilityGate;
433       }
434       
435       /**
436        * Übergibt das Log-Gate. Hier das Stop-Gate, da beim Beenden des
437        * Prozesses kein Log-Eintrag geschrieben werden soll.
438        */
439       public Gate getLogGate()
440       {
441         return getStopGate();
442       }
443    }