001    package market.statistics;
002    
003    import java.util.Calendar;
004    import java.util.Iterator;
005    
006    import market.CIArticle;
007    import market.MarketCalendar;
008    import market.SMarket;
009    import market.UCustomer;
010    import data.CountingStock;
011    import data.events.VetoException;
012    import data.ooimpl.CatalogImpl;
013    
014    
015    /**
016     * Represents a statistics of one month. It contains the statistics of every single offered
017     * article and more general information such as paid wages and miscellaneous costs.
018     * This class is also used as container in which overall statistics of a given range of time are brought
019     * together.
020     * The items of this catalog are {@link CISalesStats}.
021     * @see Statistics#getOverallStats(int, int, int, int)
022     */
023    public class CSalesStats extends CatalogImpl {
024    
025        /**
026             * ID for serialization.
027             */
028            private static final long serialVersionUID = -8964534366271134720L;
029            
030            private int month, year;
031        private int costs, wages;
032        private int revenue = 0;
033    
034        /**
035         * Creates a new statistics container. To month that those statistics have been recorded is passed
036         * via the parameters.
037         * @param year the year in which the statistics were recorded.
038         * @param month the month in which the statistics were recorded.
039         */
040        public CSalesStats(int year, int month) {
041            super(year + "-" + (month < 10 ? "0" : "") + month);
042            this.year = year;
043            this.month = month;
044            Iterator it = SMarket.getArticleCatalog().keySet(null).iterator();
045            while (it.hasNext()) {
046                String id = (String)it.next();
047                CISalesStats ciss = new CISalesStats(id, 0, 0);
048                add(ciss, null);
049            }
050        }
051    
052        /**
053         * @return the statistic's year
054         */
055        public int getYear() {
056            return year;
057        }
058    
059        /**
060         * @return the statistic's month
061         */
062        public int getMonth() {
063            return month;
064        }
065    
066        /**
067         * Initializes the {@link CISalesStats#priceHistory price history} of each article with the current
068         * article's bid. This initial bid is used for calculating average prices over a range of time.
069         * Without it, it would be possible to have an empty price history for the chosen range of time which
070         * makes calculations on this history more difficult.<br>
071         * This method is called only on creation of a CCustomerStats, but it cannot be put into the
072         * constructor, because there are cases when the initialization is not desired.
073         * @see Statistics#getArticleStats(String, int, int, int, int)
074         * @see Statistics#getOverallStats(int, int, int, int)
075         * @see SMarket#c_dailyStats
076         */
077        public void initPriceHistory() {
078            Iterator it = keySet(null).iterator();
079            while (it.hasNext()) {
080                String id = (String)it.next();
081                CISalesStats ciss = get(id);
082                Calendar c = new MarketCalendar(year, month, 1);
083                if (c.before(SMarket.getDateOfOpening())) {
084                    c = SMarket.getDateOfOpening();
085                }
086                //set new price to first day of month or market's opening (only necessary for very first month)
087                ciss.newPriceSet(c, SMarket.getArticleCatalog().get(id).getBid());
088            }
089        }
090    
091        /**
092         * @param key the key of the CISalesStats to be returned.
093         * @return the CISalesStats with the according key.
094         */
095        public CISalesStats get(String key) {
096            try {
097                return (CISalesStats)super.get(key, null, false);
098            }
099            catch (VetoException e) {
100                return null;
101            }
102        }
103    
104        /**
105         * Adds a customer's purchase to the article statistics.
106         * @param customer the customer whose purchase is to be added.
107         * @param discount the discount allowed by the market.
108         */
109        public void addSales(UCustomer customer, double discount) {
110            CountingStock cs = customer.getShoppingBasket();
111            Iterator it = cs.keySet(null).iterator();
112            while (it.hasNext()) {
113                String id = (String)it.next();
114                CIArticle cia = SMarket.getArticleCatalog().get(id);
115                int price = cia.getBid();
116                int amount = cs.countItems(id, null);
117                int revenue = new Double((amount*price)*(1-discount)).intValue();
118                CISalesStats oldEntry = get(id);
119                oldEntry.addAmount(amount);
120                oldEntry.addRevenue(revenue);
121            }
122        }
123    
124        /**
125         * Adds the current date to the order history of an article's statistics, whenever the manager
126         * purchases it.
127         * @see CISalesStats#ordered
128         *
129         * @param cs the manager's purchase.
130         */
131        public void updateOrderHistory(CountingStock cs) {
132            Iterator it = cs.keySet(null).iterator();
133            while (it.hasNext()) {
134                String id = (String)it.next();
135                int amount = cs.countItems(id, null);
136                CISalesStats entry = get(id);
137                entry.ordered(SMarket.getTime(), amount); //update order history
138            }
139        }
140    
141        /**
142         * Adds the value customer's purchase to this month's revenue.
143         * @param revenue the revenue to be added.
144         */
145        public void addRevenue(int revenue) {
146            this.revenue += revenue;
147        }
148    
149        /**
150         * @return this month's revenue.
151         */
152        public int getRevenue() {
153            return revenue;
154        }
155    
156        /**
157         * Sets the miscellaneous costs of the market. Only used while instance of this class represents
158         * the current month.
159         * @param costs the costs to be set.
160         */
161        public void setCosts(int costs) {
162            this.costs = costs;
163        }
164    
165        /**
166         * @return this month's miscellaneous costs.
167         */
168        public int getCosts() {
169            return costs;
170        }
171    
172        /**
173         * @return the costs of all article purchases the manager has made this month.
174         */
175        public int getOrderCosts() {
176            Iterator it = keySet(null).iterator();
177            int sum = 0;
178            while (it.hasNext()) {
179                String id = (String)it.next();
180                CISalesStats ciss = get(id);
181                sum += ciss.getOrderAmount() * SMarket.getArticleCatalog().get(id).getOffer();
182            }
183            return sum;
184        }
185    
186        /**
187         * Saves the sum of the employee's wages. Only used when month ends and statistics are saved to
188         * {@link CCompleteStats}
189         * @param wages the wages to be set.
190         */
191        public void setWages(int wages) {
192            this.wages = wages;
193        }
194    
195        /**
196         * @return the saved wages. Will not work if instance of this class represents current month's statistics.
197         */
198        public int getWages() {
199            return wages;
200        }
201    
202        public String toString() {
203            return "CSalesStats " + getName();
204        }
205    
206        /**
207         * Adds the all order histories which are stored in a different CSalesStats to this one.<br>
208         * Using this method multiple times creates a complete order history for any desired range of time.
209         * With the help of {@link #getOrderCosts()} it is now possible to easily compute the total of
210         * money spent on purchases during that time.
211         *
212         * @param csToAdd the CSalesStats, which contains the order histories to be added.
213         * @see Statistics#getOverallStats(int, int, int, int)
214         */
215        public void addOrders(CSalesStats csToAdd) {
216            Iterator it = keySet(null).iterator();
217            while (it.hasNext()) {
218                String id = (String)it.next();
219                CISalesStats thisCiss = get(id);
220                CISalesStats newCiss = csToAdd.get(id);
221                thisCiss.appendOrderHistory(newCiss.getOrderHistory());
222            }
223        }
224    }