001    package market;
002    
003    import market.stdform.ButtonIDs;
004    import market.stdform.FSCheckable;
005    import market.stdform.FSSellerBill;
006    import market.stdform.FSSellerCustomerTable;
007    import market.stdform.FSSellerOrderTable;
008    import market.stdform.MSLogOff;
009    import sale.FormSheet;
010    import sale.FormSheetContentCreator;
011    import sale.Gate;
012    import sale.GateChangeTransition;
013    import sale.SaleProcess;
014    import sale.SalesPoint;
015    import sale.Transition;
016    import sale.UIGate;
017    import sale.stdforms.MsgForm;
018    import users.User;
019    import data.IntegerValue;
020    import data.Value;
021    import data.events.VetoException;
022    import data.stdforms.SingleTableFormSheet;
023    
024    
025    /**
026     * The seller process. This process handles the payment of the orders.
027     */
028    public class SProcessSeller extends SProcessMarket{
029    
030        /**
031         * Gate for selecting customers.
032         */
033        private UIGate uig_customerSelection = new UIGate(null, null);
034    
035        /**
036         * Gate for affirming the cancel of the order of the currently selected customer
037         * and for displaying lost articles in case of shortages.
038         */
039        private UIGate uig_cancelBuy = new UIGate(null, null);
040    
041        /**
042         * Gate for affirming the order of the currently selected customer.
043         */
044        private UIGate uig_order = new UIGate(null, null);
045    
046        /**
047         * Gate for selecting discount and mode of payment.
048         */
049        private UIGate uig_commit = new UIGate(null, null);
050    
051        /**
052         * Gate for displaying that no customer is selected.
053         */
054        private UIGate uig_noCustomer = new UIGate(null, null);
055    
056        /**
057         * Gate for displaying that the payment was successful.
058         */
059        private UIGate uig_log = new UIGate(null, null);
060    
061        /**
062         * Table that shows the queue of customers
063         */
064        private SingleTableFormSheet stfs_customerQueue;
065    
066        /**
067         * FormSheet that shows the bill
068         */
069        private FSCheckable fs_sellerBill;
070    
071        /**
072         * The UCustomer associated to the currently selected SICustomer
073         */
074        private UCustomer uc_customer;
075    
076        /**
077         * The currently selected SICustomer
078         */
079        private SICustomer sic_customer;
080    
081    
082        /**
083         * @param name the name of the process.
084         */
085        public SProcessSeller(String name){
086            super(name);
087        }
088    
089    
090        // ############################ Gates #####################################
091    
092        /**
093         * Attaches {@link FSSellerCustomerTable}, its actions and the menu to {@link #uig_customerSelection}.
094         * @return the set up {@link #uig_customerSelection}.
095         */
096        protected Gate getInitialGate() {
097            stfs_customerQueue = FSSellerCustomerTable.getCustomerTable(SMarket.getTillQueue());
098            stfs_customerQueue.setGate(uig_customerSelection);
099    
100            setTransition(stfs_customerQueue, changeToOrderGate(), ButtonIDs.BTN_OK);
101            setTransition(stfs_customerQueue, changeToCancelBuyGate(), ButtonIDs.BTN_CANCEL);
102    
103            uig_customerSelection.setFormSheet(stfs_customerQueue);
104            uig_customerSelection.setMenuSheet(new MSLogOff());
105            return uig_customerSelection;
106        }
107    
108        /**
109         * Attaches a {@link MsgForm} and its ok-action to {@link #uig_cancelBuy}.
110         * @return the set up {@link #uig_cancelBuy}.
111         */
112        protected Gate getCancelBuyGate(){
113            FormSheet fs = new MsgForm("Auftrag stornieren?",
114                    "Sind Sie sicher, dass sie den Auftrag von "
115                    + uc_customer.getFullName() +
116                    " stornieren wollen?");
117    
118            fs.addContentCreator(new FormSheetContentCreator(){
119                protected void createFormSheetContent(FormSheet fs) {
120                     fs.getButton(FormSheet.BTNID_OK).setAction(new sale.Action(){
121                        public void doAction(SaleProcess p, SalesPoint sp) throws Throwable {
122                            uig_cancelBuy.setNextTransition(cancelBuy());
123                        }
124                    });
125                    fs.addButton("Zurück", FormSheet.BTNID_CANCEL, new sale.Action(){
126                        public void doAction(SaleProcess p, SalesPoint sp) throws Throwable {
127                            uig_cancelBuy.setNextTransition(GateChangeTransition.CHANGE_TO_ROLLBACK_GATE);
128                        }
129                    });
130                }
131            });
132    
133            uig_cancelBuy.setFormSheet(fs);
134            return uig_cancelBuy;
135        }
136    
137        /**
138         * Attaches a {@link MsgForm} and its ok-action to {@link #uig_noCustomer}.
139         * @return the set up {@link #uig_noCustomer}.
140         */
141        protected Gate getNoCustomerGate(){
142            FormSheet fs = new MsgForm("Kein Kunde selektiert", "Sie müssen zunächst einen Kunden auswählen!");
143            setTransition(fs, GateChangeTransition.CHANGE_TO_ROLLBACK_GATE, FormSheet.BTNID_OK);
144            uig_noCustomer.setFormSheet(fs);
145            return uig_noCustomer;
146        }
147    
148        /**
149         * Attaches {@link FSSellerOrderTable} and its actions to {@link #uig_order}.
150         * @return the set up {@link #uig_order}.
151         */
152        protected Gate getOrderGate(){
153            FormSheet fs = FSSellerOrderTable.getOrderTable(uc_customer.getShoppingBasket(),
154                sic_customer);
155            setTransition(fs, GateChangeTransition.CHANGE_TO_COMMIT_GATE, ButtonIDs.BTN_ACCEPT);
156            setTransition(fs, GateChangeTransition.CHANGE_TO_ROLLBACK_GATE, ButtonIDs.BTN_BACK);
157            uig_order.setFormSheet(fs);
158            return uig_order;
159        }
160    
161        /**
162         * Attaches {@link FSSellerBill} and its actions to {@link #uig_commit}.
163         * @return the set up {@link #uig_commit}.
164         */
165        public Gate getCommitGate() {
166            fs_sellerBill = FSSellerBill.create(uc_customer.getShoppingBasket().sumStock(
167                        null,
168                        CIArticle.getCatalogItemValue(),
169                        new IntegerValue(0)),
170                        uc_customer.getDiscount());
171    
172            setAction(fs_sellerBill, new sale.Action(){
173                public void doAction(SaleProcess p, SalesPoint sp) throws Throwable {
174                    if(fs_sellerBill.checkTextFields(FSCheckable.ALL_ERRORMESSAGES_AT_ONCE, false)){
175                        uig_commit.setNextTransition(changeToConfirmationGate());
176                    }
177                }
178            }, ButtonIDs.BTN_ACCEPT);
179            setTransition(fs_sellerBill, new GateChangeTransition(getOrderGate()), ButtonIDs.BTN_BACK);
180    
181            uig_commit.setFormSheet(fs_sellerBill);
182            return uig_commit;
183        }
184    
185        /**
186         * @return the Gate to jump to if the selected customer has to be rolled back.
187         */
188        public Gate getRollbackGate() {
189            return new Gate(){
190                public Transition getNextTransition(SaleProcess pOwner, User usr)
191                        throws InterruptedException {
192                    return new Transition(){
193                        public Gate perform(SaleProcess pOwner, User usr) {
194                            pOwner.getBasket().rollback();
195                            uc_customer = null;
196                            sic_customer = null;
197                            return getInitialGate();
198                        }
199                    };
200                }
201            };
202        }
203    
204        /**
205         * Attaches {@link MsgForm} and its ok-action to {@link #uig_log}.
206         * @return the set up {@link #uig_log}.
207         */
208        public Gate getLogGate() {
209            FormSheet fs = new MsgForm("Bezahlung erfolgt!",
210                        "Der Kaufvorgang wurde abgeschlossen, die Artikel werden so schnell wie möglich ausgeliefert!");
211            setTransition(fs, changeToCustomerSelectionGate(), FormSheet.BTNID_OK);
212            uig_log.setFormSheet(fs);
213            return uig_log;
214        }
215    
216        // ####################### Transitions ##############################
217    
218        /**
219         * @return a Transition that changes to the {@link #getInitialGate()} and logs the process.
220         */
221        private Transition changeToCustomerSelectionGate(){
222            return new Transition(){
223                public Gate perform(SaleProcess p, User usr) {
224                    try {
225                      p.log (p);
226                    }
227                    catch (java.io.IOException ioe) {
228                      throw new Error ("Exception occurred while logging process: " + ioe);
229                    }
230                    return getInitialGate();
231                }
232            };
233        }
234    
235        /**
236         * @return a Transition that changes to the {@link #getInitialGate()},
237         * puts the articles of the selected customer back to the markets offer
238         * and removes the customer permanently from the till-queue.
239         */
240        private Transition cancelBuy(){
241            return new Transition(){
242                public Gate perform(SaleProcess pOwner, User usr) {
243                    SMarket.getOffer().addStock(uc_customer.getShoppingBasket(), null, true);
244                    pOwner.getBasket().commit();
245                    return getInitialGate();
246                }
247            };
248        }
249    
250        /**
251         * @return a Transition that changes to the {@link #getCancelBuyGate()}, if a customer is selected,
252         * otherwise it will change to the {@link #getNoCustomerGate()}
253         */
254        private Transition changeToCancelBuyGate(){
255            return new Transition(){
256                public Gate perform(SaleProcess pOwner, User usr) {
257                    if(stfs_customerQueue.getSelectedRecord()==null){
258                        return getNoCustomerGate();
259                    }
260                    else{
261                        setCustomer();
262                        return getCancelBuyGate();
263                    }
264                }
265            };
266        }
267    
268        /**
269         * @return a Transition that changes to the {@link #getOrderGate()}, if a customer is selected,
270         * otherwise it will change to the {@link #getNoCustomerGate()}
271         */
272        private Transition changeToOrderGate(){
273            return new Transition(){
274                public Gate perform(SaleProcess pOwner, User usr) {
275                    if(stfs_customerQueue.getSelectedRecord()==null){
276                        return getNoCustomerGate();
277                    }
278                    else{
279                        setCustomer();
280                        return getOrderGate();
281                    }
282                 }
283            };
284        }
285    
286        /**
287         * @return a Transition that changes to {@link #getLogGate()},
288         * adds the customers order to order-queue and
289         * adds the payed money to markets account
290         */
291        private Transition changeToConfirmationGate(){
292            return new Transition(){
293                public Gate perform(SaleProcess pOwner, User usr) {
294                    Value v = ((FSSellerBill)fs_sellerBill.getFormSheet()).getEndSum();
295                        double discount = Conversions.round(
296                                Double.valueOf(Conversions.convertComma(
297                                fs_sellerBill.getEntry(FSSellerBill.JTFC_DISCOUNT))).doubleValue(), 3);
298                    //show statistics not until day-end closing, so store them im dailyStats
299                    SMarket.getDailySalesStats().addSales(uc_customer, discount);
300                    SMarket.getDailySalesStats().addRevenue(Conversions.valueToInt(v));
301                    SMarket.getCustomerStats().addSales(uc_customer, v);
302                    SMarket.addToAccount(v);
303                    if(uc_customer.getShoppingBasket().size(null)>0) SICustomer.addToOrderQueue(uc_customer);
304                    pOwner.getBasket().commit();
305                    uc_customer = null;
306                    sic_customer = null;
307                    return getLogGate();
308                }
309            };
310        }
311    
312    
313        // ########################### private methods #########################################
314    
315        /**
316         * Sets customer from tableselection and remove it from customer-queue
317         */
318        private void setCustomer(){
319            sic_customer = (SICustomer)stfs_customerQueue.getSelectedRecord();
320            uc_customer = sic_customer.getCustomer();
321            try {
322                sic_customer.getStock().remove(sic_customer, this.getBasket());
323            } catch (VetoException e) {
324                System.err.println(e.getMessage());
325            }
326        }
327    }