001    package data.stdforms.twotableformsheet;
002    
003    import sale.*;
004    
005    import data.*;
006    import data.stdforms.*;
007    
008    import users.*;
009    
010    /**
011     * MoveStrategy for a Catalog source and a DataBasket destination.
012     *
013     * @author Steffen Zschaler
014     * @version 2.0 20/08/1999
015     * @since v2.0
016     */
017    public class CDBStrategy extends MoveStrategy {
018    
019        /**
020         * Get the sub-process that will move items from the source to the destination.
021         *
022         * @param p the process into which the sub-process wil be embedded.
023         * @param sp the SalesPoint, if any, at which the FormSheet is being displayed.
024         * @param cSource the source Catalog.
025         * @param dbDest the destination DataBasket.
026         * @param ci the CatalogItem that is selected in the source.
027         * @param ttfs the FormSheet that triggers the process.
028         *
029         * @override Never
030         */
031        public Transition getMoveToDestProcess(SaleProcess p, SalesPoint sp, Catalog cSource, DataBasket dbDest,
032                CatalogItem ci, TwoTableFormSheet ttfs) {
033            return new GateChangeTransition(getCheckMoveToDestGate(p, sp, cSource, dbDest, ci, ttfs));
034        }
035    
036        /**
037         * Get the first gate of the sub-process that will move items from the source to the destination.
038         *
039         * <p>This Gate will check whether the move is allowable, and if so, will trigger a Transition that
040         * performs it.</p>
041         *
042         * @param p the process into which the sub-process wil be embedded.
043         * @param sp the SalesPoint, if any, at which the FormSheet is being displayed.
044         * @param cSource the source Catalog.
045         * @param dbDest the destination DataBasket.
046         * @param ci the CatalogItem that is selected in the source.
047         * @param ttfs the FormSheet that triggers the process.
048         *
049         * @override Never Instead, override {@link #checkMoveToDest} and/or {@link #moveToDest}.
050         */
051        protected Gate getCheckMoveToDestGate(SaleProcess p, final SalesPoint sp, final Catalog cSource,
052                final DataBasket dbDest, final CatalogItem ci, final TwoTableFormSheet ttfs) {
053            return new Gate() {
054                public Transition getNextTransition(SaleProcess p, User u) throws InterruptedException {
055                    int nCheckReturn = checkMoveToDest(p, sp, cSource, dbDest, ci);
056    
057                    if (nCheckReturn == 0) {
058                        return new Transition() {
059                            public Gate perform(SaleProcess p, User u) {
060                                moveToDest(p, sp, cSource, dbDest, ci);
061    
062                                return ttfs.getGate();
063                            }
064                        };
065                    } else {
066                        error(p, nCheckReturn);
067    
068                        return new GateChangeTransition(ttfs.getGate());
069                    }
070                }
071            };
072        }
073    
074        /**
075         * Check whether the indicated move is allowable. If so, return 0, otherwise return a non-zero error value
076         * that can be passed on to {@link sale.stdforms.FormSheetStrategy#error}. You can assume that you are at a {@link Gate}.
077         *
078         * @param p the process into which the sub-process wil be embedded.
079         * @param sp the SalesPoint, if any, at which the FormSheet is being displayed.
080         * @param cSource the source Catalog.
081         * @param dbDest the destination DataBasket.
082         * @param ci the CatalogItem that is selected in the source.
083         *
084         * @override Sometimes The default implementation returns 0.
085         */
086        protected int checkMoveToDest(SaleProcess p, SalesPoint sp, Catalog cSource, DataBasket dbDest,
087                CatalogItem ci) throws InterruptedException {
088            return 0;
089        }
090    
091        /**
092         * Move the indicated item from source to destination. You can assume that you are in a {@link Transition}.
093         *
094         * @param p the process into which the sub-process wil be embedded.
095         * @param sp the SalesPoint, if any, at which the FormSheet is being displayed.
096         * @param cSource the source Catalog.
097         * @param dbDest the destination DataBasket.
098         * @param ci the CatalogItem that is selected in the source.
099         *
100         * @override Sometimes
101         */
102        protected void moveToDest(SaleProcess p, SalesPoint sp, Catalog cSource, DataBasket dbDest,
103                CatalogItem ci) {
104            try {
105                cSource.remove(ci, dbDest);
106            }
107            catch (DataBasketConflictException dbce) {
108                error(p, DATABASKET_CONFLICT_ERROR);
109            }
110            catch (data.events.VetoException ve) {
111                error(p, REMOVE_VETO_EXCEPTION);
112            }
113        }
114    
115        /**
116         * Get the sub-process that will move items from the destination to the source.
117         *
118         * @param p the process into which the sub-process wil be embedded.
119         * @param sp the SalesPoint, if any, at which the FormSheet is being displayed.
120         * @param cSource the source Catalog.
121         * @param dbDest the destination DataBasket.
122         * @param ci the CatalogItem that is selected in the destination.
123         * @param ttfs the FormSheet that triggers the process.
124         *
125         * @override Never
126         */
127        public Transition getMoveToSourceProcess(SaleProcess p, SalesPoint sp, Catalog cSource, DataBasket dbDest,
128                CatalogItem ci, TwoTableFormSheet ttfs) {
129            return new GateChangeTransition(getCheckMoveToSourceGate(p, sp, cSource, dbDest, ci, ttfs));
130        }
131    
132        /**
133         * Get the first gate of the sub-process that will move items from the destination to the source.
134         *
135         * <p>This Gate will check whether the move is allowable, and if so, will trigger a Transition that
136         * performs it.</p>
137         *
138         * @param p the process into which the sub-process wil be embedded.
139         * @param sp the SalesPoint, if any, at which the FormSheet is being displayed.
140         * @param cSource the source Catalog.
141         * @param dbDest the destination DataBasket.
142         * @param ci the CatalogItem that is selected in the destination.
143         * @param ttfs the FormSheet that triggers the process.
144         *
145         * @override Never Instead, override {@link #checkMoveToSource} and/or {@link #moveToSource}.
146         */
147        protected Gate getCheckMoveToSourceGate(SaleProcess p, final SalesPoint sp, final Catalog cSource,
148                final DataBasket dbDest, final CatalogItem ci, final TwoTableFormSheet ttfs) {
149            return new Gate() {
150                public Transition getNextTransition(SaleProcess p, User u) throws InterruptedException {
151                    int nCheckReturn = checkMoveToSource(p, sp, cSource, dbDest, ci);
152    
153                    if (nCheckReturn == 0) {
154                        return new Transition() {
155                            public Gate perform(SaleProcess p, User u) {
156                                moveToSource(p, sp, cSource, dbDest, ci);
157    
158                                return ttfs.getGate();
159                            }
160                        };
161                    } else {
162                        error(p, nCheckReturn);
163    
164                        return new GateChangeTransition(ttfs.getGate());
165                    }
166                }
167            };
168        }
169    
170        /**
171         * Check whether the indicated move is allowable. If so, return 0, otherwise return a non-zero error value
172         * that can be passed on to {@link sale.stdforms.FormSheetStrategy#error}. You can assume that you are at a {@link Gate}.
173         *
174         * @param p the process into which the sub-process wil be embedded.
175         * @param sp the SalesPoint, if any, at which the FormSheet is being displayed.
176         * @param cSource the source Catalog.
177         * @param dbDest the destination DataBasket.
178         * @param ci the CatalogItem that is selected in the destination.
179         *
180         * @override Sometimes The default implementation returns
181         * {@link ProcessErrorCodes#NOT_ENOUGH_ELEMENTS_ERROR} if the destination DataBasket contains no entry that
182         * describes the given CatalogItem.
183         */
184        protected int checkMoveToSource(SaleProcess p, SalesPoint sp, Catalog cSource, DataBasket dbDest,
185                CatalogItem ci) throws InterruptedException {
186            if (!dbDest.contains(DataBasketConditionImpl.specificCatalogItem(ci))) {
187                return NOT_ENOUGH_ELEMENTS_ERROR;
188            } else {
189                return 0;
190            }
191        }
192    
193        /**
194         * Move the indicated item from the destination to the source. You can assume that you are in a
195         * {@link Transition}.
196         *
197         * @param p the process into which the sub-process wil be embedded.
198         * @param sp the SalesPoint, if any, at which the FormSheet is being displayed.
199         * @param cSource the source Catalog.
200         * @param dbDest the destination DataBasket.
201         * @param ci the CatalogItem that is selected in the destination.
202         *
203         * @override Sometimes
204         */
205        protected void moveToSource(SaleProcess p, SalesPoint sp, Catalog cSource, DataBasket dbDest,
206                CatalogItem ci) {
207            try {
208                cSource.add(ci, dbDest);
209            }
210            catch (DuplicateKeyException dke) {
211                error(p, DUPLICATE_KEY_EXCEPTION);
212            }
213            catch (DataBasketConflictException dbce) {
214                error(p, DATABASKET_CONFLICT_ERROR);
215            }
216        }
217    }