001    package market;
002    
003    import java.util.Calendar;
004    
005    import market.statistics.CISalesStats;
006    import market.statistics.Statistics;
007    import market.stdform.ButtonIDs;
008    import market.stdform.FSCheckable;
009    import market.stdform.FSEditPersonData;
010    import market.stdform.FSManagerArticleStatsDetail;
011    import market.stdform.FSManagerArticleStatsMain;
012    import market.stdform.FSManagerCustomerOverview;
013    import market.stdform.FSManagerCustomerStatsDetail;
014    import market.stdform.FSManagerCustomerStatsMain;
015    import market.stdform.FSManagerEmployeeOverview;
016    import market.stdform.FSManagerOffer;
017    import market.stdform.FSManagerOpenClose;
018    import market.stdform.FSManagerOpenPurchaseOrderDetail;
019    import market.stdform.FSManagerOpenPurchaseOrderMain;
020    import market.stdform.FSManagerOptions;
021    import market.stdform.FSManagerOverallStats;
022    import market.stdform.FSManagerPurchase;
023    import market.stdform.FSManagerPurchaseConfirm;
024    import market.stdform.MSLogOff;
025    import market.swing.JCTimeRangeBoxes;
026    import sale.Action;
027    import sale.FormSheet;
028    import sale.FormSheetContentCreator;
029    import sale.Gate;
030    import sale.GateChangeTransition;
031    import sale.JDisplayDialog;
032    import sale.MenuSheet;
033    import sale.MenuSheetItem;
034    import sale.SaleProcess;
035    import sale.SalesPoint;
036    import sale.Shop;
037    import sale.Transition;
038    import sale.UIGate;
039    import data.CatalogItemValue;
040    import data.CountingStock;
041    import data.DataBasket;
042    import data.DataBasketConditionImpl;
043    import data.DoubleValue;
044    import data.IntegerValue;
045    import data.Value;
046    import data.events.VetoException;
047    import data.ooimpl.CountingStockImpl;
048    import data.ooimpl.DataBasketImpl;
049    import data.stdforms.SingleTableFormSheet;
050    import data.stdforms.TwoTableFormSheet;
051    
052    /**
053     * The manager process. This process handles all interaction with the manager's {@link SalesPoint}.
054     */
055    public class SProcessManager extends SProcessMarket {
056    
057        /**
058             * ID for serialization.
059             */
060            private static final long serialVersionUID = -4347833144592036577L;
061    
062            /**
063         * Gate for opening and closing the market.
064         */
065        private UIGate gateOpenClose                = new UIGate(null, null);
066    
067        /**
068         * Gate for setting some calculation variables.
069         */
070        private UIGate gateOptions                  = new UIGate(null, null);
071    
072        /**
073         * Gate for purchasing some articles for the market.
074         */
075        private UIGate gatePurchaseMain             = new UIGate(null, null);
076    
077        /**
078         * Gate for confirming a purchase.
079         */
080        private UIGate gatePurchaseConfirm          = new UIGate(null, null);
081    
082        /**
083         * Gate for displaying an overview of orders that have not yet arrived.
084         */
085        private UIGate gateOpoMain                  = new UIGate(null, null);
086    
087        /**
088         * Gate for displaying details of an that has not yet arrived.
089         */
090        private UIGate gateOpoDetail                = new UIGate(null, null);
091    
092        /**
093         * Gate for displaying the market's articles and their amount.
094         */
095        private UIGate gateStockMain                = new UIGate(null, null);
096    
097        /**
098         * Gate for viewing, selecting, adding and removing employees.
099         */
100        private UIGate gateEmplEditMain             = new UIGate(null, null);
101    
102        /**
103         * Gate for editing an employee's data.
104         */
105        private UIGate gateEmplEditDetail           = new UIGate(null, null);
106    
107        /**
108         * Gate for viewing, selecting and removing customers.
109         */
110        private UIGate gateCustEditMain             = new UIGate(null, null);
111    
112        /**
113         * Gate for viewing a customer's personal data.
114         */
115        private UIGate gateCustEditDetail           = new UIGate(null, null);
116    
117        /**
118         * Gate for selecting an article and a range of time for statistics.
119         */
120        private UIGate gateArticleStatsMain         = new UIGate(null, null);
121    
122        /**
123         * Gate for viewing detailed article statistics.
124         */
125        private UIGate gateArticleStatsDetail       = new UIGate(null, null);
126    
127        /**
128         * Gate for selecting a customer whose statistics should be displayed.
129         */
130        private UIGate gateCustomerStatsMain        = new UIGate(null, null);
131    
132        /**
133         * Gate for viewing a customer's statistics.
134         */
135        private UIGate gateCustomerStatsDetail      = new UIGate(null, null);
136    
137        /**
138         * Gate for the overall statistics.
139         */
140        private UIGate gateOverallStats             = new UIGate(null, null);
141        private MenuSheet menu = createManagerMenuSheet();
142        private DataBasket dbPurchase;
143        private CountingStock csPurchase;
144    
145        /**
146         * The last date the manger ordered something. This variable necessary for creating the indexes of
147         * the open purchase orders.
148         */
149        private Calendar dateLastOrder;
150    
151        /**
152         * A counting variable for open purchase orders. If there are more than one orders a day, they are
153         * distinguished by a running number which is created with the help of this variable.
154         */
155        private int intLastOrder = 0;
156    
157        public SProcessManager() {
158            super("Manager");
159        }
160    
161        /**
162         * This method is needed by {@link SaleProcess} to know on which gate to start.
163         * @return the initial gate, i.e. the {@link Gate} where the process starts.
164         */
165        public Gate getInitialGate() {
166            return getStockMainGate();
167        }
168    
169        /**
170         * Attaches {@link FSManagerOpenClose}, its actions and the menu to {@link #gateOpenClose}.
171         * @return the set up {@link #gateOpenClose}.
172         */
173        private UIGate getOpenCloseGate() {
174            final FormSheet fsmoc = new FSManagerOpenClose();
175            fsmoc.addContentCreator(new FormSheetContentCreator() {
176                            private static final long serialVersionUID = 4884514784532918550L;
177                            public void createFormSheetContent(final FormSheet fs) {
178                    //open market
179                    fs.getButton(ButtonIDs.BTN_START).setAction(new Action() {
180                                            private static final long serialVersionUID = 1268405891376688950L;
181                                            public void doAction(SaleProcess p, SalesPoint sp) {
182                            SMarket.getTheMarket().setOpen(0);
183                            SMarket.fireMarketOpened();
184                        }
185                    });
186                    //close market (end of day)
187                    fs.getButton(ButtonIDs.BTN_END).setAction(new Action() {
188                                            private static final long serialVersionUID = 2846974728815438079L;
189                                            public void doAction(SaleProcess p, SalesPoint sp) {
190                            int error = 0;
191                            if (Shop.getTheShop().getSalesPoints().size() > 1) error = 1;
192                            if (SMarket.getTillQueue().size(null) > 0) error = 2;
193                            switch (error) {
194                                case 1:
195                                    JDDShowMessage.showMessageDialog(fs,
196                                          "Es sind noch nicht alle SalesPoints geschlossen", "Fehler");
197                                    break;
198    
199                                case 2:
200                                    JDDShowMessage.showMessageDialog(fs,
201                                          "Es wurden noch nicht alle Kunden bedient.", "Fehler");
202                                    break;
203                                default:
204                                    SMarket.getTheMarket().setOpen(2);
205                            }
206                        }
207                    });
208                    //next day
209                    fs.getButton(ButtonIDs.BTN_NEXT).setAction(
210                        new Action() {
211                                                    private static final long serialVersionUID = 2642215322790503688L;
212    
213                                            public void doAction(SaleProcess p, SalesPoint sp) {
214                              SMarket.setNextDay();
215                        }
216                    });
217                }
218            });
219    
220            //open market
221            setAction(fsmoc, new Action() {
222                            private static final long serialVersionUID = -326553716575268919L;
223    
224                    public void doAction(SaleProcess p, SalesPoint sp) {
225                        SMarket.getTheMarket().setOpen(0);
226                        SMarket.fireMarketOpened();
227                    }}, ButtonIDs.BTN_START);
228            //close market
229            setAction(fsmoc, new Action() {
230                            private static final long serialVersionUID = 5402506224408132908L;
231    
232                    public void doAction(SaleProcess p, SalesPoint sp) {
233                        int error = 0;
234                        if (Shop.getTheShop().getSalesPoints().size() > 1) error = 1;
235                        if (SMarket.getTheMarket().getStock(SMarket.STK_TILLQUEUE).size(null) > 0) error = 2;
236                        switch (error) {
237                            case 1:
238                                JDDShowMessage.showMessageDialog(fsmoc,
239                                      "Es sind noch nicht alle SalesPoints geschlossen", "Fehler");
240                                break;
241    
242                            case 2:
243                                JDDShowMessage.showMessageDialog(fsmoc,
244                                      "Es wurden noch nicht alle Kunden bedient.", "Fehler");
245                                break;
246                            default:
247                                SMarket.getTheMarket().setOpen(2);
248                        }
249                    }}, ButtonIDs.BTN_END);
250            //advance time
251            setAction(fsmoc, new Action() {
252                            private static final long serialVersionUID = -2416121507610947291L;
253    
254                    public void doAction(SaleProcess p, SalesPoint sp) {
255                        SMarket.setNextDay();
256                    }}, ButtonIDs.BTN_NEXT);
257    
258            gateOpenClose.setFormSheet(fsmoc);
259            gateOpenClose.setMenuSheet(menu);
260            return gateOpenClose;
261        }
262    
263        /**
264         * Attaches {@link FSManagerOptions}, its actions and the menu to {@link #gateOptions}.
265         * @return the set up {@link #gateOptions}.
266         */
267        private UIGate getOptionsGate() {
268            final FSCheckable fsc = new FSCheckable(new FSManagerOptions());
269            //accept settings
270            setAction(fsc, new Action() {
271                            private static final long serialVersionUID = 7905381581546545985L;
272    
273                    public void doAction(SaleProcess p, SalesPoint sp) {
274                        if (fsc.checkTextFields(FSCheckable.ALL_ERRORMESSAGES_AT_ONCE, false)) {
275                            Options options = SMarket.getOptions();
276                            int error = 0;
277                            if (Double.valueOf(Conversions.convertComma(
278                                    fsc.getEntry(FSManagerOptions.JTFC_MAX_DISCOUNT))).doubleValue() > 100)
279                                error = 1;
280                            switch (error) {
281                                case 1:
282                                    JDDShowMessage.showMessageDialog(fsc, "Es können nicht mehr als " +
283                                            "100% Rabatt gewährt werden.", "Zu viel Rabatt");
284                                default:
285                                    options.setDiscountRange(Integer.valueOf(
286                                            fsc.getEntry(FSManagerOptions.JTFC_DISCOUNT_RANGE)).intValue());
287                                    options.setDiscountValue(Integer.valueOf(
288                                            fsc.getEntry(FSManagerOptions.JTFC_DISCOUNT_VALUE)).intValue());
289                                    options.setMaxDiscount(Double.valueOf(Conversions.convertComma(
290                                            fsc.getEntry(FSManagerOptions.JTFC_MAX_DISCOUNT))).
291                                            doubleValue() / 100);
292                                    options.setFractionOfWages(Double.valueOf(Conversions.convertComma(
293                                            fsc.getEntry(FSManagerOptions.JTFC_FRACTION_OF_WAGES))).
294                                            doubleValue() / 100);
295                                    options.setTimeOfEmployment(Double.valueOf(Conversions.convertComma(
296                                            fsc.getEntry(FSManagerOptions.JTFC_SENIORITY))).
297                                            doubleValue() / 100);
298                                    SMarket.getMonthlySalesStats().setCosts(Conversions.currencyToInt(
299                                            fsc.getEntry(FSManagerOptions.JTFC_COSTS), true));
300                            }
301                        }
302                    }}, ButtonIDs.BTN_ACCEPT);
303            gateOptions.setFormSheet(fsc);
304            gateOptions.setMenuSheet(menu);
305            return gateOptions;
306        }
307    
308        /**
309         * Attaches {@link FSManagerOffer} and the menu to {@link #gateStockMain}.
310         * @return the set up {@link #gateStockMain}.
311         */
312        private UIGate getStockMainGate() {
313            final SingleTableFormSheet stfs = FSManagerOffer.create();
314            gateStockMain.setFormSheet(stfs);
315            gateStockMain.setMenuSheet(menu);
316            return gateStockMain;
317        }
318    
319        /**
320         * Attaches {@link FSManagerPurchase}, its actions and the menu to {@link #gatePurchaseMain}.
321         * @param cs the manager's "shopping basket", it can be empty or already filled with articles.
322         * @param db the transaction's DataBasket.
323         * @return the set up {@link #gatePurchaseMain}.
324         */
325        private UIGate getPurchaseMainGate(CountingStock cs, DataBasket db) {
326            //Create FormSheet with saved DataBasket and CountingStock if needed. If not, create new ones.
327            final TwoTableFormSheet ttfs = FSManagerPurchase.create(gatePurchaseMain,
328                    cs == null ? new CountingStockImpl("Einkauf", SMarket.getArticleCatalog()) : cs,
329                    db == null ? new DataBasketImpl() : db);
330            //Buy
331            setAction(ttfs, new Action() {
332                            private static final long serialVersionUID = -6576606907692825570L;
333    
334                    public void doAction(SaleProcess p, SalesPoint sp) {
335                        csPurchase = (CountingStock)ttfs.getRightTableSource();
336                        dbPurchase = ttfs.getDataBasket();
337                        //if no items bought, print error message
338                        if (!dbPurchase.contains(DataBasketConditionImpl.ALL_ENTRIES)) {
339                            JDDShowMessage.showMessageDialog(ttfs, "Bitte wählen sie Artikel zum Kauf aus.",
340                                    "Keine Auswahl getroffen");
341                        } else {
342                            //sum up prices of all selected Articles
343                            DoubleValue dv = new DoubleValue(0);
344                            csPurchase.sumStock(dbPurchase, CatalogItemValue.EVALUATE_OFFER, dv);
345                            int toPay = Conversions.currencyToInt(dv.toString(), false);
346                            //Transition to gate purchaseConfirm
347                            gatePurchaseMain.setNextTransition(new GateChangeTransition(
348                                    getPurchaseConfirmGate(toPay)));
349                        }
350                    }}, ButtonIDs.BTN_BUY);
351            gatePurchaseMain.setFormSheet(ttfs);
352            gatePurchaseMain.setMenuSheet(menu);
353            return gatePurchaseMain;
354        }
355    
356        /**
357         * Attaches {@link FSManagerPurchaseConfirm} and its actions to {@link #gatePurchaseConfirm}.
358         * @param toPay the money to pay for the manager's purchase.
359         * @return the set up {@link #gatePurchaseConfirm}.
360         */
361        private UIGate getPurchaseConfirmGate(final int toPay) {
362            final FormSheet fsmpc = new FSManagerPurchaseConfirm(toPay);
363            //buy (commit db, add cs to offerStock) and go back to purchaseMain with right table being empty
364            setAction(fsmpc, new Action() {
365                            private static final long serialVersionUID = -3925328238480326071L;
366    
367                    public void doAction(SaleProcess p, SalesPoint sp) {
368                        dbPurchase.commit();
369                        //create id for new order (current date and consecutive number)
370                        Calendar now = SMarket.getTime();
371                        if (dateLastOrder == null) {
372                            dateLastOrder = (Calendar)now.clone();
373                        }
374                        if (dateLastOrder.before(now)) {
375                            dateLastOrder = (Calendar)now.clone();
376                            intLastOrder = 1;
377                        } else {
378                            intLastOrder++;
379                        }
380                        String newIDDate = dateLastOrder.toString();
381                        CIOpenPurchaseOrders opo = new CIOpenPurchaseOrders(newIDDate, intLastOrder,
382                                csPurchase);
383                        SMarket.getOpenPurchaseOrder().add(opo, null);
384                        //add this order to statistics
385                        SMarket.getMonthlySalesStats().updateOrderHistory(opo.getOrders());
386                        gatePurchaseConfirm.setNextTransition(new GateChangeTransition(
387                                getPurchaseMainGate(null, null)));
388                        //subtract purchase from account
389                        SMarket.subtractFromAccount(new IntegerValue(toPay));
390                    }}, ButtonIDs.BTN_OK);
391            //go back to purchaseMain and find right table as it has been left so one can edit his purchase
392            setAction(fsmpc, new Action() {
393                            private static final long serialVersionUID = 6591343498920717093L;
394    
395                    public void doAction(SaleProcess p, SalesPoint sp) {
396                        ((UIGate)p.getCurrentGate()).setNextTransition(
397                                new GateChangeTransition(getPurchaseMainGate(csPurchase, dbPurchase)));
398                    }}, ButtonIDs.BTN_BACK);
399            //cancel purchase and go back to purchaseMain with right table being empty
400            setAction(fsmpc, new Action() {
401                            private static final long serialVersionUID = -7467089028432871913L;
402    
403                    public void doAction(SaleProcess p, SalesPoint sp) {
404                        dbPurchase.rollback();
405                        gatePurchaseConfirm.setNextTransition(new GateChangeTransition(
406                                getPurchaseMainGate(csPurchase, dbPurchase)));
407                    }}, ButtonIDs.BTN_CANCEL);
408            gatePurchaseConfirm.setFormSheet(fsmpc);
409            return gatePurchaseConfirm;
410        }
411    
412        /**
413         * Attaches {@link FSManagerOpenPurchaseOrderMain}, its actions and the menu to {@link #gateOpoMain}.
414         * @return the set up {@link #gateOpoMain}.
415         */
416        private UIGate getOpoMainGate() {
417            final SingleTableFormSheet stfs = FSManagerOpenPurchaseOrderMain.create();
418            //view details of the selected order
419            setAction(stfs, new Action() {
420                            private static final long serialVersionUID = -5902015261140571571L;
421    
422                    public void doAction(SaleProcess p, SalesPoint sp) {
423                        CIOpenPurchaseOrders selRec = (CIOpenPurchaseOrders)stfs.getSelectedRecord();
424                        if (selRec == null)
425                            JDDShowMessage.showMessageDialog(stfs, "Bitte wählen sie eine Lieferung aus.",
426                                    "Auswahl treffen");
427                        else
428                            ((UIGate)p.getCurrentGate()).setNextTransition(new GateChangeTransition(
429                                    getOpoDetailGate(selRec)));
430                    }}, ButtonIDs.BTN_DETAIL);
431            gateOpoMain.setFormSheet(stfs);
432            gateOpoMain.setMenuSheet(menu);
433            return gateOpoMain;
434        }
435    
436        /**
437         * Attaches {@link FSManagerOpenPurchaseOrderDetail}, its actions and the menu to {@link #gateOpoDetail}.
438         * @param opo the open purchase order to be viewed.
439         * @return the set up {@link #gateOpoDetail}.
440         */
441        private UIGate getOpoDetailGate(CIOpenPurchaseOrders opo) {
442            FormSheet fsmopod = FSManagerOpenPurchaseOrderDetail.create(opo);
443            //go back to overview
444            setTransition(fsmopod, new GateChangeTransition(getOpoMainGate()), ButtonIDs.BTN_BACK);
445            gateOpoDetail.setFormSheet(fsmopod);
446            gateOpoDetail.setMenuSheet(menu);
447            return gateOpoDetail;
448        }
449    
450    
451        /**
452         * Attaches {@link FSManagerEmployeeOverview}, its actions and the menu to {@link #gateEmplEditMain}.
453         * @return the set up {@link #gateEmplEditMain}.
454         */
455        private UIGate getEmplEditMainGate() {
456            final FSManagerEmployeeOverview fsmeo = new FSManagerEmployeeOverview();
457            //button add (merely a transition, but defined as action because of circular reference)
458            setAction(fsmeo, new Action() {
459                            private static final long serialVersionUID = -7508914767137733399L;
460    
461                    public void doAction(SaleProcess p, SalesPoint sp) {
462                        ((UIGate)p.getCurrentGate()).setNextTransition(
463                                new GateChangeTransition(getEmplEditDetailGate(null)));
464                    }}, ButtonIDs.BTN_ADD);
465            //button edit
466            setAction(fsmeo, new Action() {
467                            private static final long serialVersionUID = -4309811559983074122L;
468    
469                    public void doAction(SaleProcess p, SalesPoint sp) {
470                        UStaffer usr = (UStaffer)fsmeo.getSelectedRecord();
471                        if (usr == null) {
472                            JDDShowMessage.showMessageDialog(fsmeo, "Bitte wählen sie einen Mitarbeiter aus.",
473                                    "Auswahl treffen");
474                        } else {
475                            ((UIGate)p.getCurrentGate()).setNextTransition(
476                                    new GateChangeTransition(getEmplEditDetailGate(usr)));
477                        }
478                    }}, ButtonIDs.BTN_EDIT);
479            //button delete
480            setAction(fsmeo, new Action() {
481                            private static final long serialVersionUID = 6270963383149695340L;
482    
483                    public void doAction(SaleProcess p, SalesPoint sp) {
484                        final UStaffer usr = (UStaffer)fsmeo.getSelectedRecord();
485                        if (usr == null) {
486                            JDDShowMessage.showMessageDialog(fsmeo, "Bitte wählen sie einen Mitarbeiter aus.",
487                                    "Auswahl treffen");
488                        } else {
489                            final Value dismissalCompensation = usr.computeDismissalCompensation();
490                            JDisplayDialog jdd = JDDShowMessage.showMessageDialog(fsmeo,
491                                    "Soll " + usr.getFullName() + " ein Entlassungsgeld in Höhe von " +
492                                    Conversions.valueToCurrency(dismissalCompensation, " Euro") +
493                                    " gezahlt werden?", "Entlassungsgeld");
494                            jdd.getFormSheet().addContentCreator(new FormSheetContentCreator() {
495                                                            private static final long serialVersionUID = -8313982518926665256L;
496    
497                                                            protected void createFormSheetContent(final FormSheet fs) {
498                                    fs.removeAllButtons();
499                                    fs.addButton("Ja", 1, new Action() {
500                                                                            private static final long serialVersionUID = -6861684870677239529L;
501    
502                                                                            public void doAction(SaleProcess p, SalesPoint sp) {
503                                            try {
504                                                UMUserBase.deleteUser(usr);
505                                                SMarket.subtractFromAccount(dismissalCompensation);
506                                            }
507                                            catch (VetoException ex) {
508                                                JDDShowMessage.showMessageDialog(fsmeo, ex.getMessage(),
509                                                        "Eingeloggt");
510                                            }
511                                            fs.cancel();
512                                        }
513                                    });
514                                    fs.addButton("Nein", 2, new Action() {
515                                                                            private static final long serialVersionUID = 4720070299004239655L;
516    
517                                                                            public void doAction(SaleProcess p, SalesPoint sp) {
518                                            try {
519                                                UMUserBase.deleteUser(usr);
520                                            }
521                                            catch (VetoException ex) {
522                                                JDDShowMessage.showMessageDialog(fsmeo, ex.getMessage(),
523                                                        "Eingeloggt");
524                                            }
525                                            fs.cancel();
526                                        }
527                                    });
528                                    fs.addButton("Abbrechen", 3, new Action() {
529                                                                            private static final long serialVersionUID = 2705882733823499498L;
530    
531                                                                            public void doAction(SaleProcess p, SalesPoint sp) {
532                                            fs.cancel();
533                                        }
534                                    });
535    
536                                }
537    
538                            });
539                        }
540                    }}, ButtonIDs.BTN_DELETE);
541            gateEmplEditMain.setFormSheet(fsmeo);
542            gateEmplEditMain.setMenuSheet(menu);
543    
544            return gateEmplEditMain;
545        }
546    
547        /**
548         * Attaches {@link FSEditPersonData}, its actions and the menu to {@link #gateEmplEditDetail}.
549         * @param usr the employee whose details are to be viewed or edited. If <code>null</code> the
550         * FormSheet's fields will be empty and a new worker can be employed.
551         * @return the set up {@link #gateEmplEditDetail}.
552         */
553        private UIGate getEmplEditDetailGate(final UStaffer usr) {
554            final FSCheckable fsc = FSEditPersonData.getStafferProfile(usr);
555            //button accept
556            setAction(fsc, new Action() {
557                            private static final long serialVersionUID = -7702159208995691027L;
558    
559                    public void doAction(SaleProcess p, SalesPoint sp) {
560                        if (fsc.checkTextFields(FSCheckable.ALL_ERRORMESSAGES_AT_ONCE, false)) {
561                            FSEditPersonData fsepd = (FSEditPersonData)fsc.getFormSheet();
562                            char[] pwd = fsepd.getPassword();
563                            //check vor special errors
564                            int error = 0;
565                            if (usr == null) { //if new user is to be added
566                                if (pwd == null)
567                                    error = 1; //the passwords must be set
568                            } else { //if old user is to be edited
569                                if (UMUserBase.getNumberOfManagers() == 1   //last manager mustn't be removed
570                                        && usr.getQualification().equals(UStaffer.MANAGER)
571                                        && !fsepd.getQualification().equals(UStaffer.MANAGER))
572                                    error = 2;  //password does not have to be set, but password and confirmation
573                                                //must at least match
574                                if (!fsepd.passwordsEqual())
575                                    error = 3;
576                            }
577                            switch (error) {
578                                case 1:
579                                    JDDShowMessage.showMessageDialog(fsc,
580                                            "Die Passwörter stimmen nicht überein oder wurden nicht gesetzt.",
581                                            "Passwort überprüfen");
582                                    break;
583                                case 2:
584                                    JDDShowMessage.showMessageDialog(fsc,
585                                            "Dies ist der letzte Manager, er darf seines Postens nicht " +
586                                            "enthoben werden.",
587                                            "Letzter Manager");
588                                    break;
589                                case 3:
590                                    JDDShowMessage.showMessageDialog(fsc,
591                                            "Die Passwörter stimmen nicht überein.",
592                                            "Passwort überprüfen");
593                                    break;
594                            }
595                            if (error == 0) {
596                                UStaffer u = null;
597                                if (usr == null) { //new user
598                                    u = (UStaffer)UMUserBase.createUser(fsc.getEntry(FSEditPersonData.
599                                            JTFC_LOGIN),
600                                            UMUserBase.SELLER,
601                                            fsepd.getQualification());
602                                } else { //existing user
603                                    u = usr;
604                                }
605                                if (u == null) { //new user, but chosen login already exists
606                                    JDDShowMessage.showMessageDialog(fsc,
607                                            "Dieses Login wurde bereits vergeben, wählen sie bitte ein anderes",
608                                            "Doppeltes Login");
609                                } else {
610                                    //both
611                                    u.setSalutation(fsepd.getSalutation());
612                                    u.setSurname(fsc.getEntry(FSEditPersonData.JTFC_NAME));
613                                    u.setFirstName(fsc.getEntry(FSEditPersonData.JTFC_FIRSTNAME));
614                                    u.setTelephone(fsc.getEntry(FSEditPersonData.JTFC_TELEPHONE));
615                                    u.setStreet(fsc.getEntry(FSEditPersonData.JTFC_STREET));
616                                    u.setCity(fsc.getEntry(FSEditPersonData.JTFC_CITY));
617                                    u.setPostcode(new Integer(
618                                            fsc.getEntry(FSEditPersonData.JTFC_POSTCODE)).intValue());
619                                    if (fsepd.isPasswordSet())
620                                        u.setPassWd(UStaffer.garblePassWD(pwd));
621                                    u.setQualification(fsepd.getQualification());
622                                    u.setSalary(Conversions.currencyToInt(
623                                            fsc.getEntry(FSEditPersonData.JTFC_SALARY), true));
624                                    ((UIGate)p.getCurrentGate()).setNextTransition(
625                                            new GateChangeTransition(getEmplEditMainGate()));
626                                }
627                            }
628                        }
629                    }}, ButtonIDs.BTN_ACCEPT);
630    
631            //button back (merely a transition, but defined as action because of circular reference)
632            setAction(fsc, new Action() {
633                            private static final long serialVersionUID = 3552849914948625578L;
634    
635                    public void doAction(SaleProcess p, SalesPoint sp) {
636                        ((UIGate)p.getCurrentGate()).setNextTransition(
637                                new GateChangeTransition(getEmplEditMainGate()));
638                    }}, ButtonIDs.BTN_BACK);
639            gateEmplEditDetail.setFormSheet(fsc);
640            gateEmplEditDetail.setMenuSheet(menu);
641            return gateEmplEditDetail;
642        }
643    
644        /**
645         * Attaches {@link FSManagerCustomerOverview}, its actions and the menu to {@link #gateCustEditMain}.
646         * @return the set up {@link #gateCustEditMain}.
647         */
648        private UIGate getCustEditMainGate() {
649            final FSManagerCustomerOverview fsmco = new FSManagerCustomerOverview();
650            //button edit
651            setAction(fsmco, new Action() {
652                            private static final long serialVersionUID = 2657646387282986673L;
653    
654                    public void doAction(SaleProcess p, SalesPoint sp) {
655                        UCustomer usr = (UCustomer)fsmco.getSelectedRecord();
656                        if (usr == null) {
657                            JDDShowMessage.showMessageDialog(fsmco, "Bitte wählen sie einen Kunden aus.",
658                                    "Auswahl treffen");
659                        } else {
660                            ((UIGate)p.getCurrentGate()).setNextTransition(
661                                    new GateChangeTransition(getCustEditDetailGate(usr)));
662                        }
663                    }}, ButtonIDs.BTN_EDIT);
664            //button delete
665            setAction(fsmco, new Action() {
666                            private static final long serialVersionUID = 6311464859876620531L;
667    
668                    public void doAction(SaleProcess p, SalesPoint sp) {
669                        UCustomer usr = (UCustomer)fsmco.getSelectedRecord();
670                        if (usr == null) {
671                            JDDShowMessage.showMessageDialog(fsmco, "Bitte wählen sie einen Kunden aus.",
672                                    "Auswahl treffen");
673                        } else {
674                            try {
675                                UMUserBase.deleteUser(usr);
676                            }
677                            catch (VetoException ex) {
678                                JDDShowMessage.showMessageDialog(fsmco,
679                                        ex.getMessage(), "Eingeloggt");
680                            }
681                        }
682                    }}, ButtonIDs.BTN_DELETE);
683            gateCustEditMain.setFormSheet(fsmco);
684            gateCustEditMain.setMenuSheet(menu);
685            return gateCustEditMain;
686        }
687    
688        /**
689         * Attaches {@link FSEditPersonData}, its actions and the menu to {@link #gateCustEditDetail}.
690         * @param usr the customer whose details are to be viewed.
691         * @return the set up {@link #gateCustEditDetail}.
692         */
693        private UIGate getCustEditDetailGate(final UCustomer usr) {
694            final FSCheckable fsc = FSEditPersonData.getCustomerProfileForManager(usr);
695            //button accept
696            setAction(fsc, new Action() {
697                            private static final long serialVersionUID = -4393247453410533947L;
698    
699                    public void doAction(SaleProcess p, SalesPoint sp) {
700                        if (fsc.checkTextFields(FSCheckable.ALL_ERRORMESSAGES_AT_ONCE, false)) {
701                            FSEditPersonData fsepd = (FSEditPersonData)fsc.getFormSheet();
702                            char[] pwd = fsepd.getPassword();
703                            //password and confirmation do not match
704                            if (!fsepd.passwordsEqual()) {
705                                JDDShowMessage.showMessageDialog(fsc,
706                                        "Die Passwörter stimmen nicht überein.",
707                                        "Passwort überprüfen");
708                            } else {
709                                //save changes
710                                if (fsepd.isPasswordSet()) usr.setPassWd(UStaffer.garblePassWD(pwd));
711                                ((UIGate)p.getCurrentGate()).setNextTransition(
712                                        new GateChangeTransition(getCustEditMainGate()));
713                            }
714                        }
715                    }}, ButtonIDs.BTN_ACCEPT);
716            //button back
717            setTransition(fsc, new GateChangeTransition(getCustEditMainGate()), ButtonIDs.BTN_BACK);
718            fsc.getButton(ButtonIDs.BTN_BACK).setCaption("Kundenübersicht");
719            //button to stats
720            fsc.addContentCreator(new FormSheetContentCreator() {
721                            private static final long serialVersionUID = -3973025365345685863L;
722    
723                            public void createFormSheetContent(final FormSheet fs) {
724                    fsc.addButton("Zur Statistik", 1, new Action() {
725                                            private static final long serialVersionUID = 652971860704594604L;
726    
727                                            public void doAction(SaleProcess p, SalesPoint sp) {
728                            ((UIGate)p.getCurrentGate()).setNextTransition(
729                                    new GateChangeTransition(getCustomerStatsDetailGate(usr)));
730                        }
731                    });
732                }
733            });
734            gateCustEditDetail.setFormSheet(fsc);
735            gateCustEditDetail.setMenuSheet(menu);
736            return gateCustEditDetail;
737        }
738    
739        /**
740         * Attaches {@link FSManagerArticleStatsMain}, its actions and the menu to {@link #gateArticleStatsMain}.
741         * @return the set up {@link #gateArticleStatsMain}.
742         */
743        private UIGate getArticleStatsMainGate(){
744            //instantiation necessary to query ComboBoxes
745            FSManagerArticleStatsMain fsmasm = new FSManagerArticleStatsMain();
746            final JCTimeRangeBoxes jctrb = fsmasm.getTimeRangeBoxes();
747            final SingleTableFormSheet stfs = FSManagerArticleStatsMain.create();
748            //button detail
749            setAction(stfs, new Action() {
750                            private static final long serialVersionUID = 7798602215852724946L;
751    
752                    public void doAction(SaleProcess p, SalesPoint sp) {
753                        int error = 0;
754                        CIArticle selRec = (CIArticle)stfs.getSelectedRecord();
755                        if (selRec == null) error = 1;
756                        if (!jctrb.isValidTimeRange()) error = 2;
757                        switch (error) {
758                            case 1:
759                                JDDShowMessage.showMessageDialog(stfs, "Bitte wählen sie einen Artikel aus.",
760                                    "Auswahl treffen");
761                                break;
762                            case 2:
763                                JDDShowMessage.showMessageDialog(stfs, "Ungültiger Zeitraum.",
764                                       "Ungültiger Zeitraum");
765                                break;
766                            default:
767                                int mFrom = jctrb.getFromMonth();
768                                int mTo = jctrb.getToMonth();
769                                int yFrom = jctrb.getFromYear();
770                                int yTo = jctrb.getToYear();
771                                ((UIGate)p.getCurrentGate()).setNextTransition(new GateChangeTransition(
772                                        getArticleStatsDetailGate(Statistics.getArticleStats(
773                                        selRec.getName(), mFrom, yFrom, mTo, yTo))));
774                        }
775                    }}, ButtonIDs.BTN_DETAIL);
776            gateArticleStatsMain.setFormSheet(stfs);
777            gateArticleStatsMain.setMenuSheet(menu);
778            return gateArticleStatsMain;
779        }
780    
781        /**
782         * Attaches {@link FSManagerArticleStatsDetail}, its actions and the menu to
783         * {@link #gateArticleStatsDetail}.
784         * @param ciss the precomputed statistics to be displayed.
785         * @return the set up {@link #gateArticleStatsDetail}.
786         */
787        public Gate getArticleStatsDetailGate(CISalesStats ciss) {
788            FormSheet fsasd = new FSManagerArticleStatsDetail(ciss);
789            //button back
790            setTransition(fsasd, new GateChangeTransition(getArticleStatsMainGate()), ButtonIDs.BTN_BACK);
791            gateArticleStatsDetail.setFormSheet(fsasd);
792            gateArticleStatsDetail.setMenuSheet(menu);
793            return gateArticleStatsDetail;
794        }
795    
796        /**
797         * Attaches {@link FSManagerCustomerStatsMain}, its actions and the menu to {@link #gateCustomerStatsMain}.
798         * @return the set up {@link #gateCustomerStatsMain}.
799         */
800        private UIGate getCustomerStatsMainGate() {
801            final FSManagerCustomerStatsMain fsmcsm = new FSManagerCustomerStatsMain();
802            //button detail
803            setAction(fsmcsm, new Action() {
804                            private static final long serialVersionUID = 8565675342446688220L;
805    
806                    public void doAction(SaleProcess p, SalesPoint sp) {
807                        UCustomer selRec = (UCustomer)fsmcsm.getSelectedRecord();
808                        int error = 0;
809                        if (selRec == null) error = 1;
810                        switch (error) {
811                            case 1:
812                                JDDShowMessage.showMessageDialog(fsmcsm, "Bitte wählen sie einen Kunden aus.",
813                                    "Auswahl treffen");
814                                break;
815                            default:
816                                ((UIGate)p.getCurrentGate()).setNextTransition(new GateChangeTransition(
817                                        getCustomerStatsDetailGate(selRec)));
818                        }
819                    }}, ButtonIDs.BTN_DETAIL);
820            gateCustomerStatsMain.setFormSheet(fsmcsm);
821            gateCustomerStatsMain.setMenuSheet(menu);
822            return gateCustomerStatsMain;
823        }
824    
825        /**
826         * Attaches {@link FSManagerCustomerStatsDetail}, its actions and the menu to
827         * {@link #gateCustomerStatsDetail}.
828         * @param uc the customer whose statistics are to be viewed.
829         * @return the set up {@link #gateCustomerStatsDetail}.
830         */
831        private UIGate getCustomerStatsDetailGate(final UCustomer uc) {
832            final FormSheet fscsd = new FSManagerCustomerStatsDetail(uc);
833            fscsd.addContentCreator(new FormSheetContentCreator() {
834                            private static final long serialVersionUID = -7071697946191121850L;
835    
836                            public void createFormSheetContent(final FormSheet fs) {
837                    //button to customer data
838                    fs.addButton("Kundendaten", 1, new Action() {
839                                            private static final long serialVersionUID = 6385271347247870972L;
840    
841                                            public void doAction(SaleProcess p, SalesPoint sp) {
842                            ((UIGate)p.getCurrentGate()).setNextTransition(
843                                    new GateChangeTransition(getCustEditDetailGate(uc)));
844                        }
845                    });
846                }
847            });
848            setTransition(fscsd, new GateChangeTransition(getCustomerStatsMainGate()), ButtonIDs.BTN_BACK);
849            fscsd.getButton(ButtonIDs.BTN_BACK).setCaption("Statistikübersicht");
850            gateCustomerStatsDetail.setFormSheet(fscsd);
851            gateCustomerStatsDetail.setMenuSheet(menu);
852            return gateCustomerStatsDetail;
853        }
854    
855        /**
856         * Attaches {@link FSManagerOverallStats} and the menu to {@link #gateOverallStats}.
857         * @return the set up {@link #gateOverallStats}.
858         */
859        private UIGate getOverallStatsGate() {
860            FormSheet fsmos = new FSManagerOverallStats();
861            gateOverallStats.setFormSheet(fsmos);
862            gateOverallStats.setMenuSheet(menu);
863            return gateOverallStats;
864        }
865    
866        /**
867         * Creates the {@link MenuSheet} for the manager process.
868         *
869         * @return the created MenuSheet.
870         */
871        private MenuSheet createManagerMenuSheet() {
872            MenuSheet msMenuBar = new MenuSheet("Bar");
873            MenuSheet msLogOff = new MSLogOff();
874            MenuSheet msWares = new MenuSheet("Waren", null, 'W');
875            MenuSheet msPersons = new MenuSheet("Personen", null, 'P');
876            MenuSheet msStatistics = new MenuSheet("Statistiken", null, 'k');
877            MenuSheetItem msiOpenClose = new MenuSheetItem("Öffnen/Schließen", null, new Action() {
878                            private static final long serialVersionUID = -3633366968919656335L;
879    
880                            public void doAction(SaleProcess p, SalesPoint sp) {
881                    ((UIGate)p.getCurrentGate()).setNextTransition(
882                            new GateChangeTransition(getOpenCloseGate()));
883                }}, 'f');
884            MenuSheetItem msiOptions = new MenuSheetItem("Einstellungen", null, new Action() {
885                            private static final long serialVersionUID = 6197839271249196109L;
886    
887                            public void doAction(SaleProcess p, SalesPoint sp) {
888                    ((UIGate)p.getCurrentGate()).setNextTransition(
889                            new GateChangeTransition(getOptionsGate()));
890                }}, 'E');
891            MenuSheetItem msiStockOverview = new MenuSheetItem("Bestand und Preis", null, new Action() {
892                            private static final long serialVersionUID = -3376000007429832195L;
893    
894                            public void doAction(SaleProcess p, SalesPoint sp) {
895                    ((UIGate)p.getCurrentGate()).setNextTransition(new GateChangeTransition(getStockMainGate()));
896                }}, 'B');
897            MenuSheetItem msiPurchase = new MenuSheetItem("Einkaufen", null, new Action() {
898                            private static final long serialVersionUID = -5953129796586047918L;
899    
900                            public void doAction(SaleProcess p, SalesPoint sp) {
901                    ((UIGate)p.getCurrentGate()).setNextTransition(getToPurchaseMain(null, null));
902                }}, 'E');
903            MenuSheetItem msiOpoMain = new MenuSheetItem("Erwartete Lieferungen", null, new Action() {
904                            private static final long serialVersionUID = -733348375476747534L;
905    
906                            public void doAction(SaleProcess p, SalesPoint sp) {
907                    ((UIGate)p.getCurrentGate()).setNextTransition(
908                            new GateChangeTransition(getOpoMainGate()));
909                }}, 'L');
910            MenuSheetItem msiEmplEdit = new MenuSheetItem("Angestellte", null, new Action() {
911                            private static final long serialVersionUID = 2712700798229090841L;
912    
913                            public void doAction(SaleProcess p, SalesPoint sp) {
914                    ((UIGate)p.getCurrentGate()).setNextTransition(
915                            new GateChangeTransition(getEmplEditMainGate()));
916                }}, 'A');
917            MenuSheetItem msiCustEdit = new MenuSheetItem("Kunden", null, new Action() {
918                            private static final long serialVersionUID = -3002846725606683316L;
919    
920                            public void doAction(SaleProcess p, SalesPoint sp) {
921                    ((UIGate)p.getCurrentGate()).setNextTransition(
922                            new GateChangeTransition(getCustEditMainGate()));
923                }}, 'K');
924            MenuSheetItem msiArticleStats = new MenuSheetItem("Artikelstatistik", null, new Action() {
925                            private static final long serialVersionUID = -3919724847608738679L;
926    
927                            public void doAction(SaleProcess p, SalesPoint sp) {
928                    ((UIGate)p.getCurrentGate()).setNextTransition(
929                            new GateChangeTransition(getArticleStatsMainGate()));
930                }}, 'A');
931            MenuSheetItem msiCustomerStats = new MenuSheetItem("Kundenstatistik", null, new Action() {
932                            private static final long serialVersionUID = -1953762444703803447L;
933    
934                            public void doAction(SaleProcess p, SalesPoint sp) {
935                    ((UIGate)p.getCurrentGate()).setNextTransition(
936                            new GateChangeTransition(getCustomerStatsMainGate()));
937                }}, 'K');
938            MenuSheetItem msiOverallStats = new MenuSheetItem("Umsatzstatistik", null, new Action() {
939                            private static final long serialVersionUID = -8766726499754454331L;
940    
941                            public void doAction(SaleProcess p, SalesPoint sp) {
942                    ((UIGate)p.getCurrentGate()).setNextTransition(
943                            new GateChangeTransition(getOverallStatsGate()));
944                }}, 'U');
945    
946            msMenuBar.add(msLogOff);
947                msLogOff.add(msiOpenClose);
948                msLogOff.add(msiOptions);
949                msLogOff.add(msLogOff.remove("exit"));
950            msMenuBar.add(msWares);
951                msWares.add(msiStockOverview);
952                msWares.add(msiPurchase);
953                msWares.add(msiOpoMain);
954            msMenuBar.add(msPersons);
955                msPersons.add(msiEmplEdit);
956                msPersons.add(msiCustEdit);
957            msMenuBar.add(msStatistics);
958                msStatistics.add(msiArticleStats);
959                msStatistics.add(msiCustomerStats);
960                msStatistics.add(msiOverallStats);
961            return msMenuBar;
962        }
963    
964      /**
965       * Helper Transition to {@link #gatePurchaseMain}.<br>
966       * <br>
967       * This transition cannot be implemented as a GateChangeTransition.<br>
968       * The reason is that getPurchaseMainGate contains a TTFS-creation method that passes
969       * gatePurchaseMain as necessary parameter for the TTFS.<br>
970       * When a user's current Gate is gatePurchaseMain and he invokes a GateChangeTransition
971       * to gatePurchaseMain via the menu, an exception would occur.<br>
972       * This is because for a GateChangeTransition the setup method for gatePurchaseMain
973       * (and therefore the TTFS-creation method) would be called while gatePurchaseMain
974       * is still active and displaying a TTFS.
975       * This method creates the TTFS after the gatePurchaseMain has already been
976       * left, thus causing no conflicts.
977       *
978       * @param cs the CountingStock containing the manager's purchase.
979       * @param db the transaction's DataBasket.
980       *
981       * @return a Transition to {@link #getPurchaseMainGate(CountingStock, DataBasket)}.
982       */
983        private Transition getToPurchaseMain(final CountingStock cs, final DataBasket db) {
984            return new Transition() {
985                            private static final long serialVersionUID = -4677517203995850904L;
986    
987                            public Gate perform(SaleProcess pOwner, users.User usr) {
988                    return getPurchaseMainGate(cs, db);
989                }
990            };
991        }
992    }