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