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