View Javadoc

1   /*
2    * EconomicsFinancial.java Created @ Jun 14, 2004
3    * 
4    * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628 BX
5    * Delft, the Netherlands. All rights reserved.
6    * 
7    * See for project information <a href="http://www.simulation.tudelft.nl/">
8    * www.simulation.tudelft.nl </a>.
9    * 
10   * The source code and binary code of this software is proprietary information
11   * of Delft University of Technology.
12   */
13  
14  package org.gscg.singleuser.interactionlayer.economics;
15  
16  import java.rmi.RemoteException;
17  import java.util.ArrayList;
18  import java.util.List;
19  
20  import nl.tudelft.simulation.event.Event;
21  import nl.tudelft.simulation.event.EventInterface;
22  import nl.tudelft.simulation.event.EventListenerInterface;
23  import nl.tudelft.simulation.event.EventProducer;
24  import nl.tudelft.simulation.event.EventType;
25  import nl.tudelft.simulation.logger.Logger;
26  import nl.tudelft.simulation.supplychain.actor.SupplyChainActor;
27  import nl.tudelft.simulation.supplychain.banking.BankAccount;
28  
29  import org.gscg.common.interactionlayer.timecontrol.GlobalRowOrColumnNumber;
30  import org.gscg.singleuser.interactionlayer.SingleUserInteractionLayerInterface;
31  import org.gscg.singleuser.interactionlayer.dataobjects.EconomicsData;
32  
33  /***
34   * The EconomicsFinancial calculates the data for the financial fields in the
35   * economics panel of a supply chain client.
36   * <p>
37   * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628 BX
38   * Delft, the Netherlands. All rights reserved.
39   * 
40   * See for project information <a href="http://www.simulation.tudelft.nl/">
41   * www.simulation.tudelft.nl </a>.
42   * 
43   * The source code and binary code of this software is proprietary information
44   * of Delft University of Technology.
45   * 
46   * @author <a
47   *         href="http://www.tbm.tudelft.nl/webstaf/stijnh/index.htm">Stijn-Pieter
48   *         van Houten </a>
49   * @author <a href="http://www.tbm.tudelft.nl/webstaf/royc/index.htm">Roy Chin
50   *         </a>
51   * @version $Revision: 1.2 $ $Date: 2005/08/09 15:43:41 $
52   * @since 1.0.0
53   */
54  public class EconomicsFinancial extends EventProducer implements
55  		EventListenerInterface
56  {
57  	/*** the serial version uid */
58  	private static final long serialVersionUID = 11L;
59  
60  	/*** updates a range of columns in the economics table */
61  	public static final EventType UPDATE_ECONOMICS_COLUMNS_DAY = new EventType(
62  			"UPDATE_ECONOMICS_COLUMNS_DAY");
63  
64  	/*** updates a range of columns in the economics table */
65  	public static final EventType UPDATE_ECONOMICS_COLUMNS_WEEK = new EventType(
66  			"UPDATE_ECONOMICS_COLUMNS_WEEK");
67  
68  	/*** updates a range of columns in the economics table */
69  	public static final EventType UPDATE_ECONOMICS_COLUMNS_MONTH = new EventType(
70  			"UPDATE_ECONOMICS_COLUMNS_MONTH");
71  
72  	/*** the supply chain actor */
73  	private SupplyChainActor actor = null;
74  
75  	/*** the interaction layer */
76  	private SingleUserInteractionLayerInterface interactionLayer = null;
77  
78  	/*** the start balance */
79  	private double startBalance = Double.NaN;
80  
81  	/*** the current balance */
82  	private double currentBalance = Double.NaN;
83  
84  	/*** the current income */
85  	private double currentDayIncome, currentWeekIncome,
86  			currentMonthIncome = 0.0;
87  
88  	/*** the current expenses */
89  	private double currentDayExpenses, currentWeekExpenses,
90  			currentMonthExpenses = 0.0;
91  
92  	/*** the current day, week or month */
93  	private int currentDay, currentWeek, currentMonth = 0;
94  
95  	/*** the current data */
96  	private EconomicsData currentEconomicsDayData, currentEconomicsWeekData,
97  			currentEconomicsMonthData = null;
98  
99  	/*** the history for the days */
100 	private ArrayList historyOfEconomicsDayData = null;
101 
102 	/*** the history for the weeks */
103 	private ArrayList historyOfEconomicsWeekData = null;
104 
105 	/*** the history for the weeks */
106 	private ArrayList historyOfEconomicsMonthData = null;
107 
108 	/*** the events to subscribe the interaction layer to */
109 	private EventType[] eventsToSubscribeOwnerTo = {
110 			EconomicsFinancial.UPDATE_ECONOMICS_COLUMNS_DAY,
111 			EconomicsFinancial.UPDATE_ECONOMICS_COLUMNS_WEEK,
112 			EconomicsFinancial.UPDATE_ECONOMICS_COLUMNS_MONTH};
113 
114 	/*** an array list with the day header values */
115 	private ArrayList dayHeaderValues = null;
116 
117 	/*** an array list with the week header values */
118 	private ArrayList weekHeaderValues = null;
119 
120 	/*** an array list with the month header values */
121 	private ArrayList monthHeaderValues = null;
122 
123 	/***
124 	 * constructs a new economics financial
125 	 * 
126 	 * @param interactionLayer the interactionlayer
127 	 * @param actor the actor
128 	 */
129 	public EconomicsFinancial(
130 			final SingleUserInteractionLayerInterface interactionLayer,
131 			final SupplyChainActor actor)
132 	{
133 		super();
134 		this.interactionLayer = interactionLayer;
135 		this.actor = actor;
136 		this.startBalance = this.actor.getBankAccount().getBalance();
137 		this.currentBalance = this.startBalance;
138 		this.currentDayIncome = 0.0;
139 		this.currentDayExpenses = 0.0;
140 
141 		this.currentWeekIncome = 0.0;
142 		this.currentWeekExpenses = 0.0;
143 
144 		this.currentMonthIncome = 0.0;
145 		this.currentMonthExpenses = 0.0;
146 
147 		this.historyOfEconomicsDayData = new ArrayList();
148 		this.historyOfEconomicsWeekData = new ArrayList();
149 		this.historyOfEconomicsMonthData = new ArrayList();
150 
151 		this.currentEconomicsDayData = new EconomicsData(
152 				GlobalRowOrColumnNumber.getCurrentNumberDay(), "",
153 				new String[]{"" + 0.0, "" + 0.0,
154 						"" + Math.round(this.currentBalance)});
155 
156 		this.currentEconomicsWeekData = new EconomicsData(
157 				GlobalRowOrColumnNumber.getCurrentNumberWeek(), "",
158 				new String[]{"" + 0.0, "" + 0.0,
159 						"" + Math.round(this.currentBalance)});
160 
161 		this.currentEconomicsMonthData = new EconomicsData(
162 				GlobalRowOrColumnNumber.getCurrentNumberMonth(), "",
163 				new String[]{"" + 0.0, "" + 0.0,
164 						"" + Math.round(this.currentBalance)});
165 
166 		// subscribe the interaction layer to events fired by this event
167 		// producer
168 		for (int i = 0; i < this.eventsToSubscribeOwnerTo.length; i++)
169 		{
170 			this.addListener(this.interactionLayer,
171 					this.eventsToSubscribeOwnerTo[i]);
172 			try
173 			{
174 				this.interactionLayer
175 						.addEventType(this.eventsToSubscribeOwnerTo[i]);
176 			} catch (RemoteException remoteException)
177 			{
178 				Logger.severe(this, "<init>", remoteException);
179 			}
180 		}
181 
182 		// subscribe to current row or column event
183 		GlobalRowOrColumnNumber.getGlobalRowOrColumnNumber()
184 				.getCustomEventProducer().addListener(this,
185 						GlobalRowOrColumnNumber.UPDATE_CURRENT_DAY);
186 		GlobalRowOrColumnNumber.getGlobalRowOrColumnNumber()
187 				.getCustomEventProducer().addListener(this,
188 						GlobalRowOrColumnNumber.UPDATE_CURRENT_WEEK);
189 		GlobalRowOrColumnNumber.getGlobalRowOrColumnNumber()
190 				.getCustomEventProducer().addListener(this,
191 						GlobalRowOrColumnNumber.UPDATE_CURRENT_MONTH);
192 
193 		// subscribe to events
194 		this.actor.getBankAccount().addListener(this,
195 				BankAccount.BANK_ACCOUNT_CHANGED_EVENT);
196 	}
197 
198 	/***
199 	 * @see nl.tudelft.simulation.event.EventListenerInterface#notify(nl.tudelft.simulation.event.EventInterface)
200 	 */
201 	public void notify(final EventInterface event) throws RemoteException
202 	{
203 		try
204 		{
205 			if (event.getType().equals(BankAccount.BANK_ACCOUNT_CHANGED_EVENT))
206 			{
207 				double oldBalance = this.currentBalance;
208 				// calculate balances
209 				this.currentBalance = ((Double) event.getContent())
210 						.doubleValue();
211 
212 				// incomes
213 				if (oldBalance < this.currentBalance)
214 				{
215 					this.currentDayIncome += (this.currentBalance - oldBalance);
216 					this.currentWeekIncome += (this.currentBalance - oldBalance);
217 					this.currentMonthIncome += (this.currentBalance - oldBalance);
218 				} else
219 				{ // expenses or no change at all
220 					this.currentDayExpenses += (oldBalance - this.currentBalance);
221 					this.currentWeekExpenses += (oldBalance - this.currentBalance);
222 					this.currentMonthExpenses += (oldBalance - this.currentBalance);
223 				}
224 
225 				this.currentEconomicsDayData.setCellValues(new String[]{
226 						"" + Math.round(this.currentDayIncome),
227 						"" + Math.round(this.currentDayExpenses),
228 						"" + Math.round(this.currentBalance)});
229 				this.historyOfEconomicsDayData.add(this.currentDay,
230 						this.currentEconomicsDayData);
231 
232 				this.currentEconomicsWeekData.setCellValues(new String[]{
233 						"" + Math.round(this.currentWeekIncome),
234 						"" + Math.round(this.currentWeekExpenses),
235 						"" + Math.round(this.currentBalance)});
236 				this.historyOfEconomicsWeekData.add(this.currentWeek,
237 						this.currentEconomicsWeekData);
238 
239 				this.currentEconomicsMonthData.setCellValues(new String[]{
240 						"" + Math.round(this.currentMonthIncome),
241 						"" + Math.round(this.currentMonthExpenses),
242 						"" + Math.round(this.currentBalance)});
243 				this.historyOfEconomicsMonthData.add(this.currentMonth,
244 						this.currentEconomicsMonthData);
245 
246 				this.updateDayData(false, false);
247 				this.updateWeekData(false, false);
248 				this.updateMonthData(false, false);
249 				return;
250 			}
251 			if (event.getType().equals(
252 					GlobalRowOrColumnNumber.UPDATE_CURRENT_DAY))
253 			{
254 				this.historyOfEconomicsDayData
255 						.add(this.currentEconomicsDayData);
256 
257 				// reset daily income and expenses
258 				this.currentDayIncome = 0.0;
259 				this.currentDayExpenses = 0.0;
260 
261 				this.currentDay = ((Integer) event.getContent()).intValue();
262 				this.currentEconomicsDayData = new EconomicsData(
263 						this.currentDay, "", new String[]{
264 								"" + Math.round(this.currentDayIncome),
265 								"" + Math.round(this.currentDayExpenses),
266 								"" + Math.round(this.currentBalance)});
267 
268 				return;
269 			}
270 			if (event.getType().equals(
271 					GlobalRowOrColumnNumber.UPDATE_CURRENT_WEEK))
272 			{
273 				this.historyOfEconomicsWeekData
274 						.add(this.currentEconomicsWeekData);
275 
276 				// reset daily income and expenses
277 
278 				this.currentWeekIncome = 0.0;
279 				this.currentWeekExpenses = 0.0;
280 
281 				this.currentWeek = ((Integer) event.getContent()).intValue();
282 				this.currentEconomicsWeekData = new EconomicsData(
283 						this.currentWeek, "", new String[]{
284 								"" + Math.round(this.currentWeekIncome),
285 								"" + Math.round(this.currentWeekExpenses),
286 								"" + Math.round(this.currentBalance)});
287 
288 				return;
289 			}
290 			if (event.getType().equals(
291 					GlobalRowOrColumnNumber.UPDATE_CURRENT_MONTH))
292 			{
293 				this.historyOfEconomicsMonthData
294 						.add(this.currentEconomicsMonthData);
295 
296 				// reset daily income and expenses
297 
298 				this.currentMonthIncome = 0.0;
299 				this.currentMonthExpenses = 0.0;
300 
301 				this.currentMonth = ((Integer) event.getContent()).intValue();
302 				this.currentEconomicsMonthData = new EconomicsData(
303 						this.currentMonth, "", new String[]{
304 								"" + Math.round(this.currentMonthIncome),
305 								"" + Math.round(this.currentMonthExpenses),
306 								"" + Math.round(this.currentBalance)});
307 				return;
308 			}
309 
310 		} catch (Exception exception)
311 		{
312 			Logger.severe(this, "notify", exception);
313 		}
314 	}
315 
316 	/***
317 	 * Method updateDayData.
318 	 * 
319 	 * @param history indicates whether history is on
320 	 * @param announce indicates whether this is an announce
321 	 */
322 	private void updateDayData(final boolean history, final boolean announce)
323 	{
324 		List dataList = new ArrayList();
325 		if (history)
326 		{
327 			for (int i = 0; i < this.historyOfEconomicsDayData.size(); i++)
328 			{
329 				dataList.add(this.historyOfEconomicsDayData.get(i));
330 			}
331 		}
332 
333 		dataList.add(new EconomicsData(this.currentDay, "", new String[]{
334 				"" + Math.round(this.currentDayIncome),
335 				"" + Math.round(this.currentDayExpenses),
336 				"" + Math.round(this.currentBalance)}));
337 
338 		if (this.dayHeaderValues == null)
339 		{
340 			this.dayHeaderValues = GlobalRowOrColumnNumber.getDayHeaderValues();
341 		}
342 
343 		// implement forecast here
344 		for (int i = this.currentDay + 1; i < this.dayHeaderValues.size(); i++)
345 		{
346 			// for layout technical reasons empty headers are added
347 			// these rows or columns should not have any data
348 			if (((String) this.dayHeaderValues.get(i)).equalsIgnoreCase(""))
349 			{
350 				dataList.add(new EconomicsData(i, "", new String[]{"" + "",
351 						"" + "", "" + ""}));
352 			} else
353 			{
354 				dataList.add(new EconomicsData(i, "", new String[]{"" + 0.0,
355 						"" + 0.0, "" + Math.round(this.currentBalance)}));
356 			}
357 		}
358 		if (announce)
359 		{
360 			try
361 			{
362 				this.interactionLayer.notifyAnnounced(new Event(
363 						EconomicsFinancial.UPDATE_ECONOMICS_COLUMNS_DAY, this,
364 						dataList));
365 			} catch (RemoteException remoteException)
366 			{
367 				Logger.severe(this, "updateDayData", remoteException);
368 			}
369 		} else
370 		{
371 
372 			this.fireEvent(new Event(
373 					EconomicsFinancial.UPDATE_ECONOMICS_COLUMNS_DAY, this,
374 					dataList));
375 		}
376 	}
377 
378 	/***
379 	 * Method updateWeekData.
380 	 * 
381 	 * @param history indicates whether history is on
382 	 * @param announce indicates whether this is an announce
383 	 */
384 	private void updateWeekData(final boolean history, final boolean announce)
385 	{
386 		List dataList = new ArrayList();
387 		if (history)
388 		{
389 			for (int i = 0; i < this.historyOfEconomicsWeekData.size(); i++)
390 			{
391 				dataList.add(this.historyOfEconomicsWeekData.get(i));
392 			}
393 		}
394 
395 		dataList.add(new EconomicsData(this.currentWeek, "", new String[]{
396 				"" + Math.round(this.currentWeekIncome),
397 				"" + Math.round(this.currentWeekExpenses),
398 				"" + Math.round(this.currentBalance)}));
399 
400 		if (this.weekHeaderValues == null)
401 		{
402 			this.weekHeaderValues = GlobalRowOrColumnNumber
403 					.getWeekHeaderValues();
404 		}
405 
406 		// implement forecast here
407 		for (int i = this.currentWeek + 1; i < this.weekHeaderValues.size(); i++)
408 		{
409 			// for layout technical reasons empty headers are added
410 			// these rows or columns should not have any data
411 			if (((String) this.weekHeaderValues.get(i)).equalsIgnoreCase(""))
412 			{
413 				dataList.add(new EconomicsData(i, "", new String[]{"" + "",
414 						"" + "", "" + ""}));
415 			} else
416 			{
417 				dataList.add(new EconomicsData(i, "", new String[]{"" + 0.0,
418 						"" + 0.0, "" + Math.round(this.currentBalance)}));
419 			}
420 		}
421 		if (announce)
422 		{
423 			try
424 			{
425 				this.interactionLayer.notifyAnnounced(new Event(
426 						EconomicsFinancial.UPDATE_ECONOMICS_COLUMNS_WEEK, this,
427 						dataList));
428 			} catch (RemoteException remoteException)
429 			{
430 				Logger.severe(this, "updateWeekData", remoteException);
431 			}
432 		} else
433 		{
434 
435 			this.fireEvent(new Event(
436 					EconomicsFinancial.UPDATE_ECONOMICS_COLUMNS_WEEK, this,
437 					dataList));
438 		}
439 	}
440 
441 	/***
442 	 * Method updateWeekData.
443 	 * 
444 	 * @param history indicates whether history is on
445 	 * @param announce indicates whether this is an announce
446 	 */
447 	private void updateMonthData(final boolean history, final boolean announce)
448 	{
449 		List dataList = new ArrayList();
450 		if (history)
451 		{
452 			for (int i = 0; i < this.historyOfEconomicsMonthData.size(); i++)
453 			{
454 				dataList.add(this.historyOfEconomicsMonthData.get(i));
455 			}
456 		}
457 
458 		dataList.add(new EconomicsData(this.currentMonth, "", new String[]{
459 				"" + Math.round(this.currentMonthIncome),
460 				"" + Math.round(this.currentMonthExpenses),
461 				"" + Math.round(this.currentBalance)}));
462 
463 		if (this.monthHeaderValues == null)
464 		{
465 			this.monthHeaderValues = GlobalRowOrColumnNumber
466 					.getMonthHeaderValues();
467 		}
468 
469 		// implement forecast here
470 		for (int i = this.currentMonth + 1; i < this.monthHeaderValues.size(); i++)
471 		{
472 			// for layout technical reasons empty headers are added
473 			// these rows or columns should not have any data
474 			if (((String) this.monthHeaderValues.get(i)).equalsIgnoreCase(""))
475 			{
476 				dataList.add(new EconomicsData(i, "", new String[]{"" + "",
477 						"" + "", "" + ""}));
478 			} else
479 			{
480 				dataList.add(new EconomicsData(i, "", new String[]{"" + 0.0,
481 						"" + 0.0, "" + Math.round(this.currentBalance)}));
482 			}
483 		}
484 
485 		if (announce)
486 		{
487 			try
488 			{
489 				this.interactionLayer.notifyAnnounced(new Event(
490 						EconomicsFinancial.UPDATE_ECONOMICS_COLUMNS_MONTH,
491 						this, dataList));
492 			} catch (RemoteException remoteException)
493 			{
494 				Logger.severe(this, "updateMonthData", remoteException);
495 			}
496 		} else
497 		{
498 			this.fireEvent(new Event(
499 					EconomicsFinancial.UPDATE_ECONOMICS_COLUMNS_MONTH, this,
500 					dataList));
501 		}
502 	}
503 
504 	/***
505 	 * Method announce.
506 	 * 
507 	 * @param announce indicates whether this is an announce
508 	 */
509 	public void announce(final boolean announce)
510 	{
511 		this.updateDayData(true, announce);
512 		this.updateWeekData(true, announce);
513 		this.updateMonthData(true, announce);
514 	}
515 }