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 }